Rate this page:

API Changelog

Compatibility Policy

Bitbucket Server (formerly Stash) aims to maintain API compatibility between minor releases (e.g. between 7.0 and 7.1). Methods and classes marked as deprecated will be removed in the next major release. For example, methods marked as deprecated in Bitbucket Server 7.1 or 7.2 will be removed in Bitbucket Server 8.0.

Bitbucket Server 7.16


New REST endpoints:

  • GET /rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/commits/{commitId}/deployments?key=<key>&environmentKey=<environmentKey>&deploymentSequenceNumber=<deploymentSequenceNumber>

get the deployment matching the specified repositorySlug, key, environmentKey and deploymentSequenceNumber.

  • DELETE /rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/commits/{commitId}/deployments?key=<key>&environmentKey=<environmentKey>&deploymentSequenceNumber=<deploymentSequenceNumber>

delete the deployment matching the specified repositorySlug, key, environmentKey and deploymentSequenceNumber.

  • POST /rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/commits/{commitId}/deployments

create or update a deployment.

Bitbucket Server 7.15

Branch deletion on merge

New Java and REST API methods have been added to configure Branch deletion on merge for Project and Repository.

DeleteAfterMergeConfigurationService.deleteConfiguration(scope), DeleteAfterMergeConfigurationService.getConfiguration(scope) and DeleteAfterMergeConfigurationService.setConfiguration(DeleteAfterMergeConfigurationRequest) introduce the ability to configure Branch deletion on merge feature.

New REST endpoints:


  • GET /rest/branch-utils/latest/projects/{key}/delete-after-merge

get if the feature is enabled for a Project.

  • POST /rest/branch-utils/latest/projects/{key}/delete-after-merge

enable or disable the feature for a Project.


  • GET /rest/branch-utils/latest/projects/{key}/repos/{slug}/delete-after-merge

get if the configuration is enabled for a Repository.

  • POST /rest/branch-utils/latest/projects/{key}/repos/{slug}/delete-after-merge

enable or disable the configuration for a Repository.

  • DELETE /rest/branch-utils/latest/projects/{key}/repos/{slug}/delete-after-merge

delete the configuration for a Repository.

Bitbucket Server 7.14

Repository size

Bitbucket 7.14 uses a different mechanism for repository size calculation to make it more efficient. Following changes are done in the Bitbucket API/SPI:

  • A new method repositorySize is added to ScmCommandFactory.
  • ScmService#getSize is deprecated and will be removed in 8.0. This method is replaced by ScmCommandFactory#repositorySize.
  • A new interface RepositorySize that represents the size of a repository.
  • A new class RepositorySizeCommandParameters that represents the additional command parameters provided to the ScmCommandFactory#repositorySize method.
  • A new method repositorySize is added to PluginCommandFactory SPI with a default implementation that returns a
    SimpleCommand returning repository size as null. The default implementation will be removed in 8.0.
  • Scm#getSize is deprecated and will be removed in 8.0. This method is replaced by PluginCommandFactory#repositorySize.
  • A new method repositorySize is added to GitCommandFactory to return a GitCommand for calculating the repository size.
  • A new interface GitCountObjectsBuilder for building git count-objects command.
  • A new method countObjects is added to GitScmCommandBuilder for creating an instance of GitCountObjectsBuilder.
  • RepositoryService#getSize uses the new command returned by ScmCommandFactory#repositorySize. A cached value is returned which may not be updated immediately after the content changes. Also, this method uses different configuration for timeout and returns 0 when the underlying command times out.

WorkTree API

Bitbucket 7.14 introduces a new API for dealing with worktree paths in repositories. A worktree is a temporary location on disk associated with a change operation and is deleted when the operation completes or when the expiry time defined for the worktree has been reached. These are different from Git worktrees which allow managing multiple generally long-lived additional working copies for a single repository.

Historically, apps that wanted to create new (merge) commits could use the free-form API exposed by ScmCommandBuilder to manually set up a worktree using git clone --no-checkout. That will no longer be possible from 8.0 because Bitbucket Server is moving to a model where Git repositories can be moved to external nodes. As a result, it will no longer be possible to run free-form git commands to (efficiently) set up local worktrees. To address this, Bitbucket 7.14 introduces a new GitWorkTree API to allow apps to set up and work with worktrees in a way that will work with repositories hosted on external nodes. The newly introduced GitWorkTreeBuilder can be used to create a GitWorkTree for a given Repository, perform operations in the context of the GitWorkTree, and optionally publish the changes back to the Repository.

App developers are strongly encouraged to investigate whether their existing apps can be built with the new API as soon as possible and provide feedback. The initial API in Bitbucket Server 7.14 should cover many use cases, but it may have gaps that would be blockers for some apps. If app developers wait until Bitbucket Server 8.0 forces them to adopt the new API, they may find it’s not possible.

In addition, since Bitbucket Mesh will use replication to provide scaling and high availability, Bitbucket needs to have strict control over updates to repositories to ensure all replicas are updated in sync. Several commands that could earlier be invoked using ScmCommandBuilder can no longer be used directly starting 8.0. Following is a comprehensive list of such commands:

"add", "apply", "bisect", "checkout", "checkout-index", "citoool", "clean", "clone", 
"commit", "commit-tree", "config", "credential", "credential-cache", "credential-store", 
"daemon", "fast-import", "filter-branch", "gc", "gui", "imap-send", "init", "init-db",
"instaweb", "ls-files", "merge-file", "merge-index", "merge-one-file", "merge-tree", 
"prune", "read-tree", "reflog", "reset", "restore", "rm", "stash", "send-email", 
"show-index", "sparse-checkout", "status", "submodule", "switch", "web--browse",
"update-index", "worktree", "write-tree"

Some of the commands in the above list will be restricted in Bitbucket 8.0 to prevent changes that could break the replication mechanism. Other commands only make sense in non-bare repositories and will only be supported in the context of a GitWorkTree.

The basic workflow for creating a set of changes in a repository using the new GitWorkTree API looks like the following:

  • Create a new GitWorkTreeBuilder for the repository using GitWorkTreeBuilderFactory#builder(Repository).

  • Create a new temporary GitWorkTree using the GitWorkTreeBuilder. This worktree is automatically deleted after the operation completes.

    • Specify the commit the worktree should check out using GitWorkTreeBuilder#commit(String).

    • Use GitWorkTreeBuilder#execute(GitWorkTreeCallback) to execute the desired change operation in the context of the temporary GitWorkTree.

  • Add or edit files using GitWorkTree#write(String, Charset, IoConsumer), or use GitWorkTree#builder() to manipulate the index directly (though Git operations such as rm and mv) and/or to create new commits.

  • Use GitWorkTree#publish(PublishGitWorkTreeParameters) to publish the HEAD commit of the worktree to the repository, using PublishGitWorkTreeParameters.Builder#branch(String, String) to specify the target branch to update. A single branch can be updated at a time, but it is possible to call GitWorkTree#publish(PublishGitWorkTreeParameters) more than once to update different branches in the lifetime of a single GitWorkTree.

For a more complete example, refer to this page.

Bitbucket Server 7.13

In Bitbucket 7.13, Bitbucket Data Center introduces a way to create reviewer groups to add to pull requests. Reviewer groups can be created on a project and repository context by users with admin permissions.

New REST endpoints:


  • GET /rest/api/latest/projects/{key}/settings/reviewer-groups/

get all the reviewer groups of a Project.

  • GET /rest/api/latest/projects/{key}/settings/reviewer-groups/{id}

get a specific reviewer group given the specified ID.

  • POST /rest/api/latest/projects/{key}/settings/reviewer-groups/

create a reviewer group.

  • PUT /rest/api/latest/projects/{key}/settings/reviewer-groups/{id}

update the name and users of a reviewer group given a specified ID.

  • DELETE /rest/api/latest/projects/{key}/settings/reviewer-groups/{id}

delete the reviewer group given a specified ID.


  • GET /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/

get all the reviewer groups of a Repository.

  • GET /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/{id}

get a specific reviewer group given a specified ID.

  • GET /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/{id}/users

retrieve the users of a reviewer group. This does not return all the users of the group, only the users who have REPO_READ permission for the specified repository.

  • POST /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/

create a reviewer group.

  • PUT /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/{id}

update the name and users of a reviewer group with a specified ID.

  • DELETE /rest/api/latest/projects/{key}/repos/{slug}/settings/reviewer-groups/{id}

delete the reviewer group given a specified ID.

The new ReviewerGroupService introduces this ability to create, edit and delete reviewer groups.

Bitbucket Server 7.9

Rolling Upgrades

Starting with Bitbucket 7.9, Bitbucket Data Center can be upgraded without downtime through a rolling upgrade. The administrative actions required to orchestrate a rolling upgrade (such as enable upgrade mode or approve upgrade) can be triggered via the Bitbucket REST API. For more details see the Rolling Upgrades REST API documentation.

Node build version

In Bitbucket 7.9 we have updated the Bitbucket API, ClusterNode, to expose getBuildVersion. When called, the semantic Bitbucket version running on the queried node is returned. Additionally, when calling the /rest/api/1.0/admin/cluster REST endpoint, each node result will include its version.

UNKNOWN application state

The enum type,ApplicationState, was updated as part of Bitbucket 7.9 to include the value UNKNOWN. This new enum value is used to indicate that the application is in an indeterminate state.

Bitbucket Server 7.8

Shutdown hooks

A new SPI ShutdownHook allows components to respond to system shutdown as soon as it is initiated. When the Bitbucket JVM is terminated gracefully (and not killed immediately), components are shutdown in different phases over a period of time. Components implementing ShutdownHook are the first ones to be notified by invoking ShutdownHook.startShutdown, which give them opportunity to prepare for shutdown e.g. drain tasks, flush data, "finalize" the state before shutdown. ShutdownHook receives Duration as parameter in ShutdownHook.startShutdown, which is the longest system will wait for it to finish its processing before shutdown process continues without it and eventually terminates it.

Build server provider

A new SPI com.atlassian.bitbucket.build.server.PluginBuildServerProvider allows plugins to act as a proxy between Bitbucket Server and a CI tool. Implement this class, and register it in the plugin's atlassian-plugin.xml file using:


This will allow Bitbucket Server to call on the plugin when a build status is created using com.atlassian.bitbucket.build.server.PluginBuildServerProvider.getBuildServer in order to record the build status as being associated with that plugin.

Build statuses that have a build server will be able to:

  • Have log and artifact links displayed in the UI, as provided by the plugin's implementation of com.atlassian.bitbucket.build.server.BuildStatusEnricher
  • Allow the user to authenticate with the CI tool (via OAuth or similar), as provided by the plugin's implementation of com.atlassian.bitbucket.build.server.operations.PluginBuildServerClient.getAuthorizationUrl
  • Allow the user to perform actions in the CI tool, as provided by the plugin's implementation of com.atlassian.bitbucket.build.server.operations.PluginBuildServerClient.getOperations and com.atlassian.bitbucket.build.server.operations.PluginBuildServerClient.performAction

Bitbucket Server 7.7

Comment Reactions

Starting in Bitbucket 7.7 responding to comments became more interesting and fun. We have added the ability to add emoji to any comment. Any "like" that is already present on a comment will be migrated and represented as a "thumbsup" emoji instead now.

CommentReactionService.addReaction, CommentReactionService.removeReaction, and CommentReactionService.getReaction introduce this ability to add a reaction, remove a reaction, and check whether a user has reacted to a comment with a specific reaction respectively.

New REST endpoints:

  • PUT /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/comments/{comment_id}/reactions/{emoticon}

can be used to add a specific emoji to a specific comment. The request header should have Content-Type: application/json.

  • DELETE /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/comments/{comment_id}/reactions/{emoticon}

can be used to remove a specific emoji to a specific comment.

NOTE: CommentLikeService has been marked as deprecated as of Bitbucket Server 7.7 and is due to be removed in Bitbucket Server 8.0. It has been replaced by the new CommentReactionService. App developers who rely on the CommentLikeService are strongly encouraged to update their code to use the new CommentReactionService directly as soon as possible to add reactions, remove reactions and get reactions.

Draft Comments

In Bitbucket Server 7.7 there is a new pull request review workflow that allows an authenticated user with permission to interact with a pull request to add draft comments only visible to that authenticated user. Once the authenticated user is finished with their pull request review they can batch publish their draft comments so that other users can see the comments.

New events that are included in this change are:

  • PullRequestReviewCommentAddedEvent - which is raised when a draft comment is added to a pull request.
  • PullRequestReviewCommentRepliedEvent - which is raised when a draft reply comment is added to a pull request.
  • PullRequestReviewDiscardedEvent - which is raised when a pull request review with draft comments is discarded.
  • PullRequestReviewFinishedEvent - which is raised when a pull request review with draft comments is completed.

The CommentState enum has also been modified to include PENDING.

PullRequestService.discardReview, PullRequestService.finishReview, and PullRequestService.getReviewThreads are new methods that discard a pull request review for the authenticated user, complete and finish a pull request review for the authenticated user, and get all the comment threads with draft comments for a pull request respectively.

CommentDao.deleteBatch has been added which deletes a batch of comments.

CommentThreadDao.searchPending has been added to get all the CommentThreads that have at least one draft comment. There are three restrictions though on this method where the Commentable supplied matches the comment, the author ID matches, and the comment state is PENDING.

The new REST endpoints:

  • DELETE /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/review

can be used to delete/discard a pull request review for the authenticated user.

  • GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/review

can be used to get all the comment threads which have draft comments for a pull request review for the authenticated user.

  • PUT /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/review

can be used to finish a pull request review and publish all the draft comments for the authenticated user so that other users can see the comments.

Bitbucket Server 7.6

Client-Side Extensions

In Bitbucket Server 7.6 we updated the Client-side Extensions to the latest version 1.2.0. This version introduces the PageExtensions extension type that can be used to create custom pages in Bitbucket product by plugin developers.

Refer to the creating page guide and the Client-side Extensions changelog for more information about the changes.

Bitbucket Server 7.4

Async HTTP hosting

Starting in Bitbucket Server 7.4, hosting requests (think git clone, git fetch, git push, etc.) made via HTTP now use ServletRequest.startAsync to perform request processing using a separate ExecutorService, rather than one of Tomcat's container threads. This frees up container threads to serve REST and UI requests instead, to ensure heavy hosting load doesn't impact UI responsiveness. It also allows use of Servlet 3.1's ReadListener and WriteListener to perform non-blocking I/O while handling requests, which allows Bitbucket Server to significantly reduce the number of threads used when running git http-backend.

If your app registers any Servlet Filters, or provides any HttpScmRequests, this new async functionality may impact your app.

App-provided filters

Apps can register their own Servlet Filters to be included in the FilterChain by using the <servlet-filter/> module descriptor. In Bitbucket Server 7.4, Filters registered this way are assumed to support async, and must explicitly opt out by adding <async-supported>false</async-supported> like this:

<servlet-filter name="My Filter" key="my-filter" class="com.atlassian.example.web.MyFilter"
  <!-- If you want your filter applied to the ASYNC dispatcher, you must specify that
       explicitly in your dispatcher list here. e.g. ASYNC,FORWARD,REQUEST. Including
       the ASYNC dispatcher on a filter that doesn't support async makes no sense. -->

Explicitly disabling async support on your filter will prevent Bitbucket Server from using Servlet 3.1 non-blocking I/O for HTTP hosting, because ReadListener and WriteListener can only be used on async requests. This will negatively impact scalability, as performing hosting operations using blocking I/O requires extra threads and imposes more overhead. Setting <async-supported>false</async-supported> is intended to be a workaround to allow app-provided Filters to block async handling while they're updated to handle async requests.

Many Filters will work correctly for async requests without any changes:

public class MyFilter implements Filter {

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
    //If your filter applies logic here, it will generally work async without changes.

    //If your filter wraps the ServletRequest or ServletResponse, those wrappers may be
    //used on another thread if the request is processed asynchronously. Generally that
    //shouldn't matter, but it's something to be aware of.
    chain.doFilter(request, response);

    //If your filter applies logic here, it will likely require updates to work correctly.

  //Other methods omitted for brevity.

For Filter implementations that have code after chain.doFilter, for async requests the request will not be completed when that code is reached. Such Filters need to be updated to check request.isAsyncStarted():

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        chain.doFilter(request, response);

        if (request.isAsyncStarted()) {
        //The request is running asynchronously. Register an AsyncListener to be notified when
        //the request completes. If the request has already completed (which, due to threading,
        //may be possible), the container will immediately call onComplete on the listener when
        //it's registered with the AsyncContext here.
        //You have to check isAsyncStarted() before calling getAsyncContext() or it may throw
        //an exception if the request is not async.
        request.getAsyncContext().addListener(new AsyncListener() {

public void onComplete(AsyncEvent event) {
        //At this point the async request has completed, so run any "after" logic.
        //You can get the "most wrapped" ServletRequest and ServletResponse from the
        //AsyncContext like this:
        AsyncContext context = event.getAsyncContext();
        runAfter(context.getRequest(), context.getResponse());

        //Or you can use the ones provided to doFilter, which were provided when the
        //AsyncListener is registered, if you passed them to addListener. If you use
        //addListener(AsyncListener) the "supplied" request/response will be null.
        //runAfter(event.getSuppliedRequest(), event.getSuppliedResponse());

        //There are other methods on the interface, but onComplete is generally what filters
        //that had processing after chain.doFilter care about. Note that onComplete will be
        //called even if onError or onTimeout are called; it will be called after them.
        }, request, response); //<- These will be the "supplied" request/response on AsyncEvent.
        } else {
        //The request was processed synchronously, so it's already complete.
        runAfter(request, response);

private void runAfter(ServletRequest request, ServletResponse response) {
        //This is the logic that would have been after chain.doFilter

App-provided HttpScmRequestHandlers and HttpScmRequests

A new isAsyncSupported() property has been added to HttpScmRequest. The default is false, so, unlike Filters, app-provided HttpScmRequest implementations will not automatically start running async. After doing local testing, app developers can override the default to indicate their HttpScmRequests support async.

Even if an HttpScmRequest returns true for isAsyncSupported(), it cannot assume it will be run that way. If any app-provided Filters block async, or if a system administrator has globally disabled async handling, HttpScmRequest implementations will be called synchronously. HttpScmRequests can check isAsyncStarted() on the HttpServletRequest to determine whether the request is running synchronously or asynchronously.

HttpScmRequests do not need to use non-blocking handling for async requests. There's no requirement that they check isAsyncStarted() and have special handling for async. In general, existing blocking handling will work as-is whether a request is run synchronously or asynchronously. The check simply allows HttpScmRequests the opportunity to use async features like ReadListener and WriteListener if they choose.

public class MyHttpScmRequestHandler implements HttpScmRequestHandler {

  public Optional<HttpScmRequest> create(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response) {
    //Don't check request.isAsyncStarted() here. The system doesn't start async processing until
    //it has verified an HttpScmRequest can be created, so it won't be async yet.
    return Optional.of(new MyHttpScmRequest(request, response));

  //Other methods omitted for brevity.

public class MyHttpScmRequest implements HttpScmRequest {

  private final HttpServletRequest request;
  private final HttpServletResponse response;

  public MyHttpScmRequest(HttpServletRequest request, HttpServletResponse response) {
    this.request = request;
    this.response = response;

  public void handleRequest() throws IOException {
    //Inside handleRequest() it's safe to check isAsyncStarted(). If the request is going to be
    //processed asynchronously, it will have happened by now.
    if (request.isAsyncStarted()) {
      //The request is running asynchronously. That means non-blocking features like ReadListener
      //and WriteListener are available.
    } else {
      //Even though this implementation _supports_ async, either we're deployed in Bitbucket Server
      //7.3 or older, or something else has blocked the request from running asynchronously.

  //This override can be _present_ even if the app still supports Bitbucket Server 7.3 and older; older
  //versions simply will not check it, and will always process requests synchronously.
  //Note that, if you want to compile your app against an older version of the HttpScmRequest SPI to
  //ensure compatibility with pre-7.4 versions, you can still add this method to allow 7.4+ to run your
  //HttpScmRequest asynchronously; just omit the @Override so it will compile.
  public boolean isAsyncSupported() {
    return true;

  //Other methods omitted for brevity.

New Rich Build-status

In Bitbucket Server 7.4 there is a new REST endpoint that supports receiving significantly more build information from a build server. This new information is presented in various places on the product, for the 7.4 release this is most prominent as a builds tab. To receive rich build-status the CI tool needs to POST Build Status via the new REST endpoint to Bitbucket Server.

New REST endpoint:

POST /rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/commits/{commitId}

We recommend using this new endpoint as it provides a better experience for users with additional test summary and duration displayed in the UI.

Repository Delete Policy

System admins can now configure the permission level needed to delete a repository by setting a repository delete policy. The permissions for setting a repository delete policy are SYS_ADMIN, ADMIN, PROJECT_ADMIN and REPO_ADMIN.

New REST endpoints:

  • PUT /rest/policies/latest/admin/repos/delete
  • GET /rest/policies/latest/admin/repos/delete

DC License Upgrade Improvements

Changed REST endpoint:

  • POST /rest/api/1.0/admin/license Returns a 400 status if the license is being changed from Server to DC, and there are Add-ons installed which will need license upgrades to DC licenses. If a parameter confirmWarning=true is supplied the license will be applied anyway and a 200 status returned.


Internationalization has been introduced into auditing. This has resulted in a number of changes in the Bitbucket API:

  • the constants in AuditCategory are now i18n property keys instead of hard-coded English values
  • the @Auditable annotation now has an action field which can be used to explicitly specify an action (instead of having it be the class name), and this the specified action can be an i18n property key
  • the category field of @Auditable can now be an i18n property key (the system will attempt to translate the provided key, and will fallback to using it as a hard-coded English value if no property exists with that key); note that all of the constants provided in AuditCategory are valid i18n keys

Additionally, the auditing model has been extended to allow setting i18n keys in place of hard-coded English values:

  • the AuditEvent.Builder constructors which take hard-coded action and category fields have been deprecated (AuditEvent.Builder(type) can be used instead)
  • in AuditEvent.Builder, actionI18nKey(..)/categoryI18nKey(..) replacing the now deprecated action(..)/category(..)
  • AuditType.fromI18nKeys(area, level, categoryI18nKey, actionI18nKey) replacing the now deprecated AuditType(area, category, action, level)
  • AuditEvent.fromI18nKeys(categoryI18nKey, actionI18nKey, level) replacing the now deprecated AuditEvent.builder(action, category, level)
  • AuditAttribute.fromI18nKeys(nameI18nKey, value) replacing the now deprecated new AuditAttribute(name, value)
  • ChangedValue.fromI18nKeys(i18nKey) and using the builder to set the from and to replacing the now deprecated new ChangedValue(key, from, to)

A number of application published audited events have changed to being audited internally. These events no longer have an @Audited annotation, and the associated converters have been deprecated.

  • AutomaticMergeEvent and AutomaticMergeConverter
  • RefRestrictionEvent and RefRestrictionEventConverter
  • SshAccessKeyEvent and SshAccessKeyEventConverter
  • SshKeyEvent and SshKeyEventConverter

Constructors have been deprecated (and replaced by constructors with additional fields) in the following application published events:

  • HookScriptUpdatedEvent
  • RefRestrictionUpdatedEvent
  • RepositoryHookSettingsChangedEvent
  • RepositoryDefaultBranchModifiedEvent

Bitbucket Server 7.2

Repository searching

In Bitbucket Server 7.2 we are adding the ability to search for repositories via REST that have a specific file at the root level of the repository.

The new REST search endpoint is:

  • GET /rest/search/latest/repos-matching-root-file?rootFile=<filename>&query=<general query term>

The query parameters which are both mandatory include:

  • rootFile which is the specific file at the root level of the repository, for example pom.xml
  • query which is a general query term, for example my-repository or project-abc


Tasks have been deprecated and replaced by Comments with severity=BLOCKER

NOTE: App developers who use tasks are strongly encouraged to update their code to use CommentService directly as soon as possible to create, retrieve and update BLOCKER comments; TaskService is now just a facade for that one.

NOTE: BLOCKER comments have existed since 6.7, however, prior to 7.0 they are not treated as tasks. Apps that wish to retain semantic compatibility with 6.x must continue using the TaskService until support for pre-7.0 releases can be dropped.

Implementing tasks as BLOCKER comments imposes two semantics-breaking changes despite remaining API-compatible with previous releases:

  • Tasks can only be deleted by their authors, and repository administrators; pull request authors can no longer delete tasks they did not create (unless they're a repository administrator)
  • Task text can only be updated by its author; pull request authors and repository administrators can no longer update the text for tasks they did not create

In addition to those semantics-breaking changes, there are other implications that may be worth noting:

  • BLOCKER comments created using the CommentService directly are included in task results, unless they are root comments (i.e. they have no parent). It was not, and still is not, possible to create a task without an anchoring comment, so root BLOCKER comments cannot be treated as tasks because they would violate the nullability contract for Task#getAnchor
  • BLOCKER comments created and/or updated using the task API still have their whitespace normalized
  • Creating, deleting and updating tasks now raises comment events, which means those task operations can be canceled using the cancelable comment events
  • Creating a new task creates a BLOCKER reply on the anchoring comment
  • Deleting a task deletes the BLOCKER reply
  • Updating a task updates the state and/or text of the BLOCKER reply

All of the types in com.atlassian.bitbucket.task have been deprecated and replaced with BLOCKER Comments. The following classes are deprecated:

  • IllegalTaskStateException
  • NoSuchTaskException
  • Task
  • TaskAnchor
  • TaskAnchorType
  • TaskAnchorVisitor
  • TaskCount
  • TaskCreateRequest
  • TaskOperations
  • TaskService
  • TaskState
  • TaskUpdateRequest

The Task REST API is deprecated, and instead the existing Comment REST API should be used as follows:

  • create - POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments (passing the attribute severity set to BLOCKER)
  • delete - DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
  • retrieve - GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
  • update - PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
  • resolve (same as update, passing the attribute state set to RESOLVED)

A new REST endpoint has been added for retrieving the BLOCKER comments for a pull request - GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/blocker-comments

It can take the following optional query parameters:

  • count=true to return only a count of the blocker comments (and not the comments themselves), grouped by state
  • state=OPEN|RESOLVED to return the blocker comments matching the given state

Bitbucket Server 7.0


Bitbucket Server 7.0 includes a major overhaul to how auditing works for the application. This includes an extended model for representing auditing data, new categorization metadata associated with every event, and changes to how audit events are provided and consumed by plugins.

Audit data model replacement

Prior to 7.0, audit events were represented by an AuditEntry on a Bitbucket Server AuditEvent. This has been replaced by a different AuditEvent, which is a cross-product replacement.

A legacy AuditEntry maps to a new AuditEvent as follows:

  • AuditEntry.getAction() has been replaced by AuditEvent.getAction()
  • AuditEntry.getProject() and AuditEntry.getRepository() have been replaced by AuditEvent.getAffectedObjects() (where a project or a repository is represented by an AuditResource)
  • AuditEntry.getDetails() and AuditEntry.getTarget() have no direct replacements, but can be represented as an AuditAttribute, which is what the system will do internally when converting from AuditEntry into AuditEvent (note that these are not guaranteed to be present on system events after 7.0, and associated data will likely be represented differently)
  • AuditEntry.getDate(), AuditEntry.getSourceIpAddress() and AuditEntry.getUser() have no replacements, but are set automatically by the system as part of processing the event, and are part of the AuditEntity constructed from the AuditEvent as AuditEntity.getTimestamp(), AuditEntity.getSource() and AuditEntity.getAuthor() respectively

Providing audit events

Prior to 7.0, plugin developers were able to add audited events to the system by annotating an event with @Audited and implementing an AuditEntryConverter. Plugin developers could also publish a Bitbucket Server AuditEvent directly. These methods of providing auditing events have been deprecated in 7.0 for removal in 8.0. These legacy methods of providing auditing events to the system do so via the deprecated AuditEntry model. The application internally makes a best effort conversion to the new AuditEvent model, which may not result in the new model being used completely.

It is recommended that plugin developers switch to using @Auditable with an AuditEventConverter. This is the new audit event provider API added in 7.0, which is used to convert directly to the new AuditEvent model. This way plugin developers can directly construct their AuditEvent and have better control over what information is included in the audit event.


The concept of audit Priority (and the associated enum) have been deprecated in 7.0 for removal in 8.0. A Priority set on an @Audited annotation will be ignored (so all events are audited regardless of priority). From 7.0 onward, using CoverageArea and CoverageLevel (via the new @Auditable annotation) can be used to attach metadata to an event to control when it should be audited.


The concept of Channels (and the associated class) have been been deprecated in 7.0 for removal in 8.0. From 7.0 onward, AuditResource's should be added to the affectedObjects property of the AuditEvent instead. AuditUtils has helper methods that can be used to create AuditResources for projects and repositories. Adding a project affectedObject ensures the audited event will appear in the project audit log, and adding a repository affectedObject ensures the audited event will appear in the repository audit log. Multiple affectedObjects can be added to a single AuditEvent if desired.

From 7.0 onward, a Channel set on an @Audited annotation will be automatically converted into a project and/or repository affectedObject, if the relevant entity is present on the AuditEntry. However it is recommended that plugin developers which to using @Auditable to be able to specify affectedObjects directly.

Consuming audit events

Prior to 7.0, plugin developers were able to listen to the Bitbucket Server AuditEvent and consume all auditing events raised by the system and other plugins. The application includes logging auditing to both a file and the database, but this allowed plugins to add additional consumers. From 7.0 onward, the application will no longer publish AuditEvent - it is only being retained as a deprecated provider API until 8.0.

Instead, any plugin wishing to consume audit events must switch to implementing the new AuditConsumer SPI from 7.0 onward.

Retrieving audit events

Prior to 7.0, certain repository and project audited actions were stored in the database, and could be retrieved via AuditService. This service has been deprecated in 7.0 for removal in 8.0. Instead, any plugin wishing to retrieve audit events should use AuditSearchService.

Attachment Metadata API

In Bitbucket Server 7.0 we are adding new Java and REST methods for saving, updating, removing and retrieving metadata for any new attachments that are added to a pull request.

AttachmentService.saveMetadata, AttachmentService.deleteMetadata, and AttachmentService.getMetadata introduce this ability to save, update, remove and retrieve any new attachment's metadata on a pull request respectively.

New REST endpoints:

  • PUT /rest/api/latest/projects/KEY/repos/SLUG/attachments/ID/metadata

can be used to save and update attachment metadata. The request header should have Content-Type: application/json and the data sent needs to be valid JSON.

  • DELETE /rest/api/latest/projects/KEY/repos/SLUG/attachments/ID/metadata

can be used to delete attachment metadata.

  • GET /rest/api/latest/projects/KEY/repos/SLUG/attachments/ID/metadata

can be used to retrieve attachment metadata.

In Bitbucket Server 7.0 we shipped a new pull request experience, which resulted in a number of changes to the API.

Introduction of Client-side Extensions

We have removed support for the existing Client Web Fragments on the pull request page and replaced them with Client-side Extensions. This will require manual migration of plugins to using Client-side Extensions in order for them to continue working on the pull request page.

We plan to continue deprecating support for Client Web Fragments and adding support for Client-side Extensions in more locations throughout Bitbucket Server.

Rename of pull request page web resource context

The bitbucket.page.pullRequest.view web resource context has been renamed to bitbucket.page.pullRequest.detail. This means that for any resources you need on the page that aren't loaded via Client-side Extensions, you will need to update the context property of the relevant Web Resource

Removal of the bitbucket.pullrequest.view plugin decorator

Support for the bitbucket.pullrequest.view plugin decorator was removed in Bitbucket Server 7.0.

Bitbucket Server 6.9


Code Insights

  • String InsightAnnotation.getPath() has been deprecated and will be removed in Bitbucket Server 8.0. Please use Optional<String> InsightAnnotation.getFilePath() instead.

Commands and Handlers

com.atlassian.bitbucket.scm.BaseCommand, a base implementation of the AsyncCommand and Command interfaces which uses Atlassian Process Utils to run processes has been deprecated for removal without replacement in Bitbucket Server 8.0. App developers who use BaseCommand directly should update their apps to use one of Bitbucket Server's CommandBuilder mechanisms instead:

Note App developers must not assume that AsyncCommand and Command instances returned by builders, or by the Git SCM's *CommandFactory types, are derived from BaseCommand. The builder and command factory interfaces only guarantee AsyncCommand and Command types; the specific implementations for those interfaces can change at any time, in any release.

Additionally, all of the types in com.atlassian.bitbucket.scm.ssh and com.atlassian.bitbucket.web.cgi, which are used to implement HTTP(S) and SSH hosting support for Git, have been deprecated for removal without replacement in Bitbucket Server 8.0. The following classes are deprecated:

  • AbstractSshStreamHandler
  • BaseCgiHandler
  • CgiEnvironmentUtils
  • CgiInputHandler
  • CgiOutputHandler
  • SshCommandExitHandler
  • SshInputHandler
  • SshOutputHandler

Bitbucket Server 6.8

CDN Support

In Bitbucket Server 6.8 we have added CDN support for caching static assets(such as JavaScript, CSS, and fonts). This includes static resources that are served by plugins. With this change, we are moving to stateless delivery of JavaScript and CSS resources. Apps that don't use the new APIs for web-resource transforms and conditions may cause static assets to be cached incorrectly.

The following web-resource transforms and conditions have been deprecated:

  • com.atlassian.plugin.webresource.transformer.WebResourceTransformer
  • com.atlassian.plugin.web.Condition

See Stateless web-resource transforms and conditions to make sure your app is using the new APIs for web-resource transforms and conditions.

Bitbucket Server 6.7

Patch API

New Java and REST API methods have been added for retrieving patches of repositories and pull requests.

ContentService.streamPatch(PatchRequest, TypeAwareOutputSupplier) and ScmExtendedCommandFactory.patch(PatchCommandParameters, TypeAwareOutputSupplier) introduce the ability to stream a patch for a given commit or commit range, along with the new ScmFeature.PATCH feature.

Two new REST endpoints:

  • GET /rest/api/latest/projects/KEY/repos/SLUG/pull-requests/<pullRequestId>.patch
  • GET /rest/api/latest/projects/KEY/repos/SLUG/patch?since=<sinceHash>&until=<untilHash>&allAncestors=[true|false]

can be used to retrieve associated patch details via REST.

Raw text diff API

New Java and REST API methods have been added for retrieving the raw text diff of repositories and pull requests.

PullRequestService.streamDiff(PullRequestDiffRequest, TypeAwareOutputSupplier), ContentService.streamDiff(DiffRequest, TypeAwareOutputSupplier) and ScmCommandFactory.diff(DiffCommandParameters, TypeAwareOutputSupplier) introduce the ability to stream a raw text diff for a given pull request or commit range.

A new REST endpoint:

  • GET /rest/api/latest/projects/KEY/repos/SLUG/pull-requests/<pullRequestId>.diff?contextLines=<contextLines>

can be used to retrieve the raw diff for a particular pull request.

Three existing REST endpoints:

  • GET /rest/api/latest/projects/KEY/repos/SLUG/pull-requests/diff/<pullRequestId>?contextLines<contextLines>=&sinceId=<sinceHash>&untilId=<untilHash>
  • GET /rest/api/latest/projects/KEY/repos/SLUG/diff?contextLines<contextLines>=&since=<sinceHash>&until=<untilHash>
  • GET /rest/api/latest/projects/KEY/repos/SLUG/commits/<commit_id>/diff?contextLines=<contextLines>&since=<sinceHash>

can be called with the request header Accept: text/plain to retrieve the raw text representation of the diff.

Bitbucket Server 6.6

New cancelable comment events

Eight new CancelableEvents allow plugins to veto the creation, modification and deletion of comments:

Bitbucket Server 6.0

Deprecated Java APIs removed

Interfaces, classes, and methods in the Bitbucket Server Java API that were previously marked as deprecated have been removed.

Plugins that use any of these interfaces (which would have generated deprecation warnings when built against Bitbucket Server 5.x) generally won’t build with Bitbucket Server 6.x

Precompiled plugins that used any of the removed interfaces will fail to install or run in Bitbucket Server 6.x, typically with java.lang.NoSuchMethodError or java.lang.ClassNotFoundExceptions.

Removal of the legacy Repository Hooks API

Bitbucket Server 5.0 introduced a new Repository Hooks and Merge Checks API. In 6.0 the legacy API has been removed. For an overview of the new API please see the Repository Hooks and Merge Checks Guide.

Removal of direct access to repositories on disk

In Bitbucket Server 5.10 direct access to the Bitbucket managed repositories on disk for plugins was deprecated. In 6.0 the deprecated API that permitted this has been removed. For further information please refer to the changelog entry for 5.10.

Removal of Notifications SPI

All public SPI available in the package com.atlassian.bitbucket.notification has been removed without replacement.

Removal of Search API

The packages com.atlassian.bitbucket.search and com.atlassian.elasticsearch.client were previously exported and available for plugins to use. These however were just implementation classes and not part of a useful search API. These packages are no longer exported as of 6.0.

Removal of Dev status API The packages com.atlassian.devstatus and com.atlassian.devstatus.vcs were previously exported and available for plugins to use. These however were just implementation classes and not part of useful API. These packages are no longer exported as of 6.0.

Removed API details

The following classes and interfaces have been removed in Bitbucket Server 6.0. Please see the linked Javadoc for Bitbucket Server 5.16 for informing regarding deprecation and possible alternative classes and interfaces.

In addition, deprecated methods in existing classes and interfaces across the whole Bitbucket Server API have been removed.

Consult the Bitbucket Server 5.16 Java API Reference for details on the removed methods, and their alternatives in Bitbucket Server 6.x.

Removal of provided Scala runtime

Previously plugins written in Scala were able to depend on Bitbucket Server to provide the Scala runtime library (org.scala-lang:scala-library) as as such did not need to bundle it in the plugin. As of Bitbucket Server 6.0 this dependency is no longer provided/exported.

AUI 8 upgrade

Bitbucket Server 6.0 upgrades Atlassian User Interface (AUI) from 7.x to 8.0 For more information on upgrading to AUI 8 see the AUI 8 upgrade guide.

Internal Web Resources blocked

Though they were never API, some plugins have depended on web-resources in the plugin com.atlassian.bitbucket.server.bitbucket-web. In 6.0, most of the dependencies will stop working. Please use an equivalent public API, if available. Some exceptions were made for heavily used resources, but these will eventually be replaced with supportable implementations of API and will also be removed a future major version update.

The temporary exceptions are:

  • :avatar-picker-dialog
  • :branch-multi-selector
  • :client-storage
  • :commits-table
  • :dom-event-util
  • :events
  • :global
  • :global-repository-selector
  • :group-multi-selector
  • :pull-request-can-merge
  • :pull-request-list-table
  • :require-lite
  • :revision-reference-selector
  • :searchable-multi-selector
  • :server-soy-templates
  • :time
  • :user-multi-selector

Internal JS/AMD modules blocked

Similar to the above, some internal AMD modules were depended on by plugins. In 6.0, third-party plugins that depend on modules starting with bitbucket/internal/ will stop working. Where an equivalent public API is available, use that. Otherwise, consider implementing your own version of the functionality. Some exceptions were made for heavily used modules, but these will eventually be replaced with supportable implementations of API and will also be removed removed a future major version update.

The temporary exceptions are:

  • bitbucket/internal/bbui/pull-request-list-table/components/summary
  • bitbucket/internal/bbui/pull-request-list-table/pull-request-list-table
  • bitbucket/internal/feature/alerts/alerts
  • bitbucket/internal/feature/pull-request/can-merge/can-merge
  • bitbucket/internal/feature/repository/branch-multi-selector/branch-multi-selector
  • bitbucket/internal/feature/repository/global-repository-selector/global-repository-selector
  • bitbucket/internal/feature/repository/revision-reference-selector/revision-reference-selector
  • bitbucket/internal/feature/user/group-multi-selector/group-multi-selector
  • bitbucket/internal/feature/user/user-multi-selector/user-multi-selector
  • bitbucket/internal/util/client-storage
  • bitbucket/internal/util/dom-event
  • bitbucket/internal/util/events
  • bitbucket/internal/util/time
  • bitbucket/internal/widget/avatar-picker-dialog/avatar-picker-dialog
  • bitbucket/internal/widget/searchable-multi-selector/searchable-multi-selector

Internal JS events blocked

Events (consumed using bitbucket/util/events) starting with bitbucket.internal have never been official API but will no longer be able to be subscribed to and should not be considered stable or part of any official API.

TextView API blocked

As a result of the changes to internal JS events and other changes, the TextView API (which was only accessibly via an internal event) will no longer be accessible. The TextView API could be used for modifying the source or diff view. Where possible it is suggested to use Code Insights to display extra information on a diff. Key methods of the TextView API were addLineClassaddLineWidget, and registerGutter/setGutterMarker.

Custom file-handlers no longer supported for diff views

Custom file-handlers are no longer supported for diff views (but continue to be supported for source views). Any custom file-handlers registered for diff-views will be ignored when resolving the appropriate handler.

Bitbucket Server 5.16

User Erasure API

In Bitbucket Server 5.16 we have introduced the ability for admins to erase personally identifiable user data for a deleted user. Personally identifiable user data stored in third party plugins will not be erased, unless those plugins implement their own com.atlassian.bitbucket.user.UserErasureHandler. For the erasure process to pick up these implementations, they have to be defined as a com.atlassian.bitbucket.user.UserErasureModuleDescriptor module in the plugin's atlassian-plugin.xml file. See the module description for <user-erasure-handler> for more information.

Bitbucket Server 5.15

Code Insights API

In Bitbucket Server 5.15 we have introduced a feature to display the results of static analysis on a pull request in the form of a report and annotations. This has included both Java and REST API for adding, modifying and deleting reports and annotations. See this how-to guide for more details.

Bitbucket Server 5.14

Data Center Migrations API

In Bitbucket Server 5.14 we have introduced a feature for migrating projects and repositories between Bitbucket installations. Data provided by third party plugins will not be migrated, unless those plugins implement their own com.atlassian.bitbucket.migration.Exporter and com.atlassian.bitbucket.migration.Importer. For the migration process to pick up these implementations, they have to be defined as a com.atlassian.bitbucket.migration.MigrationHandlerModuleDescriptor module in the plugin's atlassian-plugin.xml file. See the module description for <migration-handler> for more information.

Bitbucket Server 5.11

Pull Request Commit API

In Bitbucket Server 5.11 we are adding Java and REST API methods for retrieving the pull requests containing a specified commit. PullRequestService.countByCommit and PullRequestService.searchByCommit introduce the ability to count or search pull requests associated with a specific commit. A new REST endpoint (/rest/api/latest/projects/KEY/repos/SLUG/commits/{commitId}/pull-requests) allows retrieval of associated pull requests via REST.

Bitbucket Server 5.10

Deprecated direct access to repositories on disk

In Bitbucket Server 5.10 we've made the difficult decision to deprecate direct access to our repositories on disk for apps. The ability to access to repositories on disk will be removed in 6.0. Deprecated interfaces and methods which will be removed without replacement include:

  • ApplicationPropertiesService.getRepositoriesDir()
  • ApplicationPropertiesService.getRepositoryDir(Repository)
  • GitAgent (All methods)
    • Accessing the default branch and resolving refs should be done using RefService instead
  • GitScmConfig (All methods)
    • GitScm.getVersion() has been added to continue to provide access to the detected Git version
    • All other methods have no planned replacements
  • ScmHookDetails.getEnvironment()

Apps which directly access repository directories and use JGit to interact with their contents will no longer be able to do so. Apps which otherwise read or modify repository contents, such as installing, updating or removing hooks, will no longer be able to do so. Executing processes other than git in repository directories will also no longer be possible.

Apps which use API services like CommitService, ContentService and RefService will be unaffected. Additionally, our CommandBuilder API (including GitCommandBuilderFactory and GitScmCommandBuilder) is also unaffected, continuing to allow app developers the ability to build and execute arbitrary git commands. Going forward, our APIs will be the only available mechanism for interacting with repository contents.

Building a system which can scale from 10 users to 50,000+ users is complicated, and there's a balance that has to be struck between our desire to provide a flexible, rich API and SPI to empower our ecosystem and the need to continuously improve how the system scales for ever-increasing user counts. We recognize that this is a decision which will negatively impact some existing apps, and those who use them. It's been a difficult decision to make internally, and one we take very seriously. However, as we consider our roadmap going forward, and the features we want to add, especially around scalability, it has become apparent that it will not be possible to deliver on our roadmap the way we want to while apps are able to make direct modifications to repositories without using our API--aside from retrieving the directory--to do so. Supporting direct access to repositories severely limits our guarantees around repository state, and about when repositories are and are not being updated, and those limitations in turn prevent us from implementing much-requested features like read-only mode and sharded repository storage.

New Watcher API

In Bitbucket Server 5.10 we are adding an API service for managing watchable entities: the WatcherService. Watchable.getWatchers() has been deprecated and WatcherService.search should be used instead. The existing Watchable's (CommitDiscussion and PullRequest) will still return their watchers from getWatchers() until the method is removed in 6.0. Repository is a new Watchable and has had a getWatchers() method added to it for compatibility, but the method is a no-op and will be removed in 6.0 also.

Bitbucket Server 5.5

New Permission API

In Bitbucket Server 5.5 we are adding API to allow plugins to restrict or extend the permissions granted to a user on a resource. Plugins may implement PermissionVoterProvider to create a PermissionVoter and register the provider in the permission-voter-provider tag in atlassian-plugin.xml in order to 'vote' on whether a user is allowed access to a given resource. For the permission check to succeed, at least one PermissionVoter must return a result of PermissionVote.GRANT. If all PermissionVoters abstain, or any PermissionVoter returns a result of PermissionVote.VETO, the permission check is unsuccessful and the user is not allowed to carry out the requested operation.

In addition to this, we are also adding a new permission level, Permission.USER_ADMIN, which represents access to change the account configuration of a user (such as SSH keys, GPG keys, personal tokens and password). The permission cannot be granted to any user/group, but callers can check for this permission using the newly added PermissionService.hasUserPermission methods.

Updated Authentication API

HttpAuthenticationHandler.authenticate and SshAuthenticationHandler.authenticate return an ApplicationUser only, with no ability for AuthenticationHandlers to add their own context. This method has been deprecated (for removal in 6.0) in favor of the new HttpAuthenticationHandler.performAuthentication and SshAuthenticationHandler.performAuthentication which returns an AuthenticationResult which contains the authenticated ApplicationUser and authentication properties provided by the handler.

Bitbucket Server 5.4

New Webhooks API

In Bitbucket Server 5.4 we are adding a Webhooks API to allow plugins to publish webhooks. Plugins will be able to import the WebhooksService from com.atlassian.webhooks to use this new feature. Plugins are also able to register to filter webhook invocations, as well as enrich invocations. This allows fine grained control over which webhooks are fired, as well as the http details for each of them. To find out more, check out WebhookFilter and WebhookRequestEnricher.

If your plugin would like to set the payload body of a webhook, please export a WebhookPayloadProvider. By default Bitbucket knows how to serialize certain application events, but if you're publishing custom webhooks, ensure that you provide a payload provider if you require a HTTP body in your webhook.

The Webhooks API source code and documentation can be found here.

net.i2p.crypto.eddsa* packages are no longer OSGi-exported

Bitbucket Server 5.0.0 added an OSGi export for net.i2p.crypto.eddsa* packages as part of upgrading the SSH library the system uses. Bitbucket Server 5.4.0 removes that export, as newer versions of the SSH library require a new version of the net.i2p.crypto:eddsa library which is API-incompatible with the previously-exported version.

Any app relying on net.i2p.crypto.eddsa packages via an OSGi import should be updated to bundle their required version of the library instead.

Bitbucket Server 5.2

Updated Hooks API

In Bitbucket Server 5.2 we are updating the hooks API to allow hooks to be configured at both a Project and a Repsitory level. Because of this, methods on the RepositoryHookService will now take a Scope object rather than a Repository object to encapsulate the Project or Repository scope to which the settings and enabled/disabled state can be applied. Additionally, in order to make the hooks API more usable, many methods now take 'request objects' (e.g. DeleteRepositoryHookRequest, RepositoryHookSearchRequest, SetRepositoryHookSettingsRequest) which is a wrapper around the Scope and other arguments required by the method. For more information on the new API and how to use it, see the Repository Hooks and Merge Checks Guide

Bitbucket Server 5.1

Pull Request Deletion

In Bitbucket Server 5.1 we are introducing the ability to delete pull requests. A new method is available on the PullRequestService to trigger a pull request deletion. Furthermore a cancelable PullRequestDeletionRequestedEvent was added, which allows plugins to veto a pull request's deletion. We're calling attention to this change to remind plugin and integration developers that pull requests and all their associated data, like comments, can disappear, and any code integrating with Bitbucket needs to account for this.

Bitbucket Server 5.0

New Comment API

As announced in the 4.11 release the Comment API has been replaced with a more usable and maintainable alternative.

A Comment now has a reference to a CommentThread which binds an entire conversation together. Comment threads provide API clients with access to:

  • the entire comment graph through it's rootComment
  • an optional CommentThreadDiffAnchor (not available for pull request general comments) which points to the location in the diff where the comment was added
  • the Commentable (currently either a PullRequest or a CommitDiscussion) which serves as the context for the thread

We have also introduced the CommentService which centralizes all comment-related APIs removing the duplication previously seen in CommitService and PullRequestService.

New Hooks API

In Bitbucket Server 5.0 we are introducing a new API for Hooks. This API will replace the existing hooks API and the merge checks API. This new API makes retrieving added and removed commits much simpler and more efficient. For more information on the new API and how to use it, see the Repository Hooks and Merge Checks Guide.

The legacy Hooks API has been deprecated for removal in Bitbucket Server 6.0.

Deprecated Java APIs removed

Interfaces, classes, and methods in the Bitbucket Server Java API that were previously marked as deprecated have been removed.

Plugins that use any of these interfaces (which would have generated deprecation warnings when built against Bitbucket Server 4.x) generally won't build with Bitbucket Server 5.x

Precompiled plugins that used any of the removed interfaces will fail to install or run in Bitbucket Server 5.x, typically with java.lang.NoSuchMethodError.

Deprecated APIs have been documented in the Bitbucket Server 4.14 Java API Reference for Bitbucket Server 5.0.

The following classes and interfaces have been removed in Bitbucket Server 5.0. Please see the linked Javadoc for Bitbucket Server 4.14 for informing regarding deprecation and possible alternative classes and interfaces.

In addition, deprecated methods in existing classes and interfaces across the whole Bitbucket Server API have been removed.

Consult the Bitbucket Server 4.14 Java API Reference for details on the removed methods, and their alternatives in Bitbucket Server 5.x.

Bitbucket Server 4.13

Mockito 2.x upgrade

Although the bitbucket-parent Maven POM file is not considered stable API, an upgrade to the version of the Mockito mocking framework is worth noting. Plugins that either use bitbucket-parent as their parent POM or import it for the purposes of "dependencyManagement" may see changes to test code as the specific Mockito version dependency may be inherited from bitbucket-parent.

Note: The Mockito framework is a test dependency only and its upgrade will not impact a plugin's compatibility with Bitbucket Server 4.13.

The upgrade from Mockito 1.x to 2.x involves a number of breaking changes. Plugin developers are encouraged to update unit tests where Mockito is used, and can find more information at What's new in Mockito 2.

For plugin developers who wish to depend on the bitbucket-parent artifact at version 4.13 or later, but still wish to continue using Mockito 1.x, can override the dependency in the POM for their own plugin. Simply add the following dependency to your plugin's pom.xml:


Bitbucket Server 4.11

Comments API deprecation

In this release we've deprecated the Comments API to make way for a more usable and maintainable alternative.

In our efforts to evolve, maintain and consume the API we've found:

  • Conversations are not explicitly represented. This causes a problem when trying to access conversation metadata (such as the anchor or the Commentable) from a Comment
  • Methods are duplicated across services
  • Tables are duplicated in the database
  • There are schema issues when backing up and restoring data in clustered systems

The upcoming API (to be published in our 5.0 release) will address these issues through the following semantic changes (and possibly others):

  • A new CommentThread interface will be introduced to be the common denominator in a conversation
  • A Comment will link back to the thread it belongs to for easy access to the conversation
  • Comment anchors will be redesigned to remove duplicate information
  • A CommentService will be made available to simplify how plugin developers create, edit and remove comments
  • Event and activity items produced by the comment API will be replaced (and in some cases removed)

Bitbucket Server 4.10

AUI bundled Raphael is deprecated

In Bitbucket Server 4.10 we upgraded AUI to version 6.0.0, which no longer bundles Raphael. The Raphael bundled with AUI was never a part of our API, it was an AUI implementation detail, however we have included a separate Raphael dependency in this version as we are aware of some apps using the Raphael that AUI exposed. This dependency is deprecated and will be removed in Bitbucket Server 5.0. If your app requires Raphael, you should bundle your own version of Raphael (or another drawing library).

Bitbucket Server 4.6

Shared Access Layer (SAL) LocaleResolver getLocale implementation change

Prior to Bitbucket Server 4.6 in the case where a user had set their Bitbucket Server language in their Account settings to "Automatically detect browser setting", and had a language set in their browser that was not one of the languages for which a language pack was installed in Bitbucket Server, calling getLocale on the SAL LocaleResolver would return a Locale based on the preferred locale they had set in their browser.

In Bitbucket Server 4.6+ the Locale returned will be the Locale that is the closest match for an installed language. This is a more correct implementation of the LocaleResolver API description which states that getLocale should return "the Locale that should be used in internationalization and localization", as now this Locale will match that used by other parts of the system for internationalization and localization.

Bitbucket Server 4.4

Pull request toolbar plugins moved and deprecated

The web sections and web items at the following locations and sections have been deprecated:

  • bitbucket.pull-request.toolbar
  • bitbucket.pull-request.toolbar.actions
  • bitbucket.pull-request.toolbar.section.user-actions

The web items have been moved into a '...' dropdown menu as menu items, and if you were relying on specific DOM rendering of your plugin, it may cease to function. We no longer refresh the page after a merge or decline, and a reviewer can be added to the pull request without a page refresh. This means your web-item may be out of date in these cases.

A live JS event handling the click event of elements matching your styleClass or <link id="" /> will continue to function until 5.0. You should convert your web-items into client-web-items and add them directly to the new section 'bitbucket.pullrequest.action'. You should remove any intermediary web-sections.

Roles updated event has been deprecated

PullRequestRolesUpdatedEvent has been deprecated for removal in 5.0. Plugin developers who wish to be notified when a user is added/removed as a reviewer should use PullRequestReviewersUpdatedEvent instead

Bitbucket Server 4.2

This public constructor on FileContentCache has been deprecated

FileContentCache now requires a FileContentCacheManager as a constructor dependency. The recommended way to build a FileContentCache is now to use the FileContentCacheManager.Builder a FileContentCache can then be created by calling FileContentCacheManager#createContentCache. NOTE Special care must be taken when migrating to the FileContentCacheManager to ensure that cacheDirectory paths remain correct.


File cacheDirectory = new File(propertiesService.getCacheDir(), CACHE_REGION);
        new FileContentCache(CACHE_KEY, cacheDirectory, new TtlCacheExpiryStrategy(), minFreeSpace, cachePump);


File cacheDirectory = new File(propertiesService.getCacheDir());
        FileContentCache cache = new FileContentCacheManager.Builder(cacheDirectory)

Stash 3.10

Branch permissions get an update

The BranchPermissionService and version 1.0 of the branch permissions REST API are being deprecated.

In Stash 3.10 we are introducing several new types of branch permissions and are adding the ability to add restrictions based on the branching model.

As a result, we are introducing a new service to interact with branch permissions, the RefRestrictionService. This service can be accessed by adding ref-restriction-api to your pom.xml as a dependency using:


Along with this change, we are updating the version of the branch permissions REST API to version 2.0. It is important to note that any REST calls to branch permissions version 1.0 using 'latest' in the REST URLs should be changed to use '1.0' instead, as version 2.0 of the REST API is not backwards compatible.

We've added new APIs to create, update and remove branch permissions:

Additionally we have added the ref-restriction-spi, which provides interfaces to allow plugin developers to create their own RefMatcher implementations. This opens up the possibility of customizing what type of Ref is restricted by a given branch permission. Add the following to your dependencies to use the ref-restriction-spi:


RepositoryMetadataService has been renamed to RefService

The RepositoryMetadataService is used to retrieve branches and tags for a repository. The "repository metadata" name isn't very self-documenting. Since the service is used to interact with the refs in a repository, it has been renamed to the RefService. The RepositoryMetadataService will remain available to plugins until it is removed in with the 4.0 release.

ChangesetReader is deprecated; use CommitReader

As part of the ongoing work to normalize the API to use "commit" instead of "changeset", the ChangesetReader has been deprecated and CommitReader has been added to take its place.

The format constants previously public on ChangesetReader are now private on CommitReader. Having the constants exposed made changing the format a semantically incompatible change because any plugins relying directly on those constants and not using the ChangesetReadert to parse the output would be broken. If plugins are parsing output for themselves, they should use their own format. If they're using the CommitReader to parse the output, they should call getFormat() on the instantiated reader to get the format and make no assumptions about the format returned.

Stash 3.7

Changeset is deprecated; long live Commit

Throughout the Stash codebase there's been a bit of a split between the term "changeset" and the term "commit". The two have often been used interchangeably, but each represents a distinct concept:

  • A commit represents a snapshot of a complete repository at a given point in time. It captures metadata about who authored the changes and when as well as, optionally, a message about why the changes were made.
    • Different SCMs may include additional metadata in their commits, but Stash's API doesn't include it
    • This was represented by Changeset in Stash
  • A changeset represents how the repository's contents changed between two commits
    • Merge commits, for example, have at least two changesets
    • This was represented by DetailedChangeset in Stash because the name Changeset was already taken

Starting from 3.7 Stash's API is being normalized, replacing Changeset with Commit and replacing DetailedChangeset with Changeset. Because this normalization will touch so many classes and interfaces, the deprecated elements will be retained through the entire 4.x release cycle and will be removed in 4.0. This means plugins developed using the now- deprecated names will continue to work, unchanged, until 4.0.

Stash 3.7 includes the following changes related to this API normalization:

  • The existing MinimalChangeset, Changeset and DetailedChangeset interfaces have been deprecated
    • All of the related data classes (InternalMinimalChangeset, InternalChangeset and InternalDetailedChangeset) have been deprecated
    • All of the related request objects (ChangesetsBetweenRequest, DetailedChangesetsRequest) have been deprecated
    • ChangesetCallback, and all of its related classes, has been deprecated
  • In parallel, completely independent MinimalCommit, Commit and Changeset interfaces have been added
    • New data classes (SimpleMinimalCommit, SimpleCommit and SimpleChangeset) have been added
    • New request objects (CommitRequest, CommitsRequest, CommitsBetweenRequest and ChangesetsRequest) have been added
    • CommitCallback, and related classes, has been added
  • All methods which return the legacy Changeset and DetailedChangeset types have been deprecated, with new variants that return the new Commit and Changeset types added alongside them

For those implementing the SCM SPI or directly using the SCM API, Stash 3.7 introduces:

Unfortunately, because PluginCommandFactory (and the more user-facing ScmCommandFactory) use the names commit and commits for their methods which return Command<Changeset> and Command<Page<Changeset>>, respectively, there is no backward-compatible way to introduce methods which return Command<Commit> and Command<Page<Commit>>. Because of this, the SCM contract will be broken in the Stash 4.0 release.

  • If you are calling any of these methods, you should update your plugin to call one of Stash's API services instead. The API services exposing each SCM command are documented on the ScmCommandFactory interface
    • Switching to an API service will allow your plugin to be compatible with both Stash 3.x and Stash 4.x, which will not be possible if you use the SCM interfaces directly
    • If you cannot switch, you'll need to release distinct versions of your plugin for 3.x and 4.x compatibility
  • If you have implemented an SCM plugin, you will need to release distinct versions of it for 3.x and 4.x compatibility

Additional changes may be made in Stash 3.8, and subsequent releases, to further normalize the API. The goal of these changes is for Stash 4.0 to have a consistent, clear API. If your plugins use the existing Changeset API we strongly encourage you to start updating them to use the new Commit API as soon as possible, and to keep an eye out for EAP builds of Stash 4.0 so you can verify their compatibility with the next major release.

Last authentication timestamps for users

In Stash 3.7, the last timestamp for users' most recent authentication is now tracked. This information cannot be reconstructed retroactively, so after the upgrade each user will have an unknown timestamp. Their next authentication will set that to the current time, and it will be tracked and updated going forward.

Authenticating via the web UI's login screen, via HTTP (pushing to or pulling from a repository over HTTP, for example) or via SSH will all update the last authentication timestamp. Browsing via the web UI will not update the timestamp for each page viewed; the timestamp will only be updated when the user gets a new session with the server. If the user has checked "Remember me", each time they get a new session with the server (generally after ~30 minutes of inactivity), their timestamp will be updated when their new session is created.

The existing DetailedUser has a new getLastAuthenticationTimestamp() accessor. That property is marshaled as "lastAuthenticationTimestamp" when the DetailedUser is returned via REST. See the documentation for /admin/users for example JSON.

Custom pull request notification SPI

In Stash 3.7, plugins can add custom sections in the pull request notifications. For an example, see the new Comment Likes notifications. Adding custom notifications is performed as follows:

  • The plugin fires an event extending CustomPullRequestNotificationEvent (using SAL's EventPublisher); the event should include a renderer ID, the intended recipients of the notification, plus any data needed to render the notification encapsulated in a CustomNotificationData object (for example in Comment Like notifications, this includes the comment ID, plus the user ID of the user who liked the comment);
  • When the pull request notification is rendered, the notifications plugin in Stash calls the registered renderer with the renderer ID included in the CustomPullRequestNotificationEvent, transforming the CustomNotificationData into a CustomNotificationSection rendered in the notification's email.
  • Users' notification preferences determine when notifications will be rendered. Notifications may be rendered several minutes later for users with batch notifications enabled.

Note that the data provided by the event (CustomPullRequestNotificationEvent.getData()) should be as lightweight as possible because it is persisted as JSON data in the database for any recipient configured to receive batched notifications. For example, use IDs (such as the repository ID and pull request ID for a pull request) rather than the full object (such as a pull request instance).

Custom notification renderers are registered by implementing the interface CustomPullRequestNotificationRenderer in a plugin and declaring it in the plugin's atlassian-plugin.xml as follows:

<custom-pull-request-notification-renderer key="my-custom-notification-renderer" class="com.myorganisation.MyCustomNotificationRenderer"/>

Custom pull request comment actions

In Stash 3.7, plugins can add custom actions to notification emails associated with pull request comments. For example, the 'Like' and 'Reply' links in pull request comment emails are implemented as custom actions. To add your own custom action to pull request notifications, declare a web-item in your plugin's atlassian-plugin.xml with section="stash.notification.comment.actions", and a <link> to the URL you want the user to navigate to when clicking on the action. For example:

<web-item key="my-comment-action" name="My Comment Action" section="stash.notification.comment.actions">
  <label key="com.myorganisation.comment.action.label" />
  <tooltip key="com.myorganisation.comment.action.tooltip" />

The custom action renders as a link below each comment in immediate and batched email notifications. Define the link that your custom action navigates to, e.g. a servlet in your plugin that performs an action before navigating to the pull request page, or a link that navigates to the comment on the pull request page and performs some action there. The ${pullRequest} and ${comment} variables are provided in the notification context to help render the web-item's link (e.g. ${pullRequest.id} and ${comment.id}).

Stash 3.5

Atlassian Soy 3.x

In Stash 3.4, the closure template (soy) compiler was upgraded to the latest version as part of the upgrade of Atlassian Soy. This includes the removal of some legacy APIs as well as a stricter compiler of soy templates. The compiler is stricter than the old compiler so some templates which were previously allow may start to have compilation errors. It is possible to write templates which are compatible with both versions. Below are some of the common errors which may occur as part of the upgrade and how to fix them.

Missing required param


template stash.feature.pullRequest.mergeHelpDialog: Call to 'aui.dialog.dialog2' is missing required param 'content'.

This is due to the strictness change in the soy compiler. the parameter on the sub template is defined as required but you are not providing it to the call. You must either mark the parameter on the sub template as optional or pass in a value for the parameter.

ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

This is due to a change in the soy compiler where it represents numbers as longs where it previously represented them as integers. This exception is most likely coming from a custom soy function you have written. Cast to a Number instead and call .intValue() or .longValue().

Comment Likes API

The comment likes feature introduced in 3.5 comes with Java and REST APIs that may be used to add, remove and query comment likes programmatically:

Stash 3.4

Properties API

Selected domain objects in Stash that inherit from PropertySupport can now have custom information associated with them. The data is stored against an entity using PropertyMap, which is essentially a map of string keys to any type of value. Properties supersede the AttributeSupport API as a more flexible alternative, with the latter being deprecated and scheduled for removal in Stash 4.0.

Alongside AttributeSupport the following attribute provider plugin modules have been deprecated and replaced with a property provider alternative. Plugin developers are encouraged to switch to property providers, as the replaced modules will be removed in Stash 4.0:

Properties must be convertible to JSON, or otherwise REST requests to resources including properties will fail.

Stash 3.3

Short (display) SHA-1 changes

In Stash 3.3, short SHA-1s are no longer generated by Git. Instead, they are now generated using a fixed length of 11 characters. This change was made because generating short SHA-1s in Git requires it to load the SHA-1s of every object in the repository for consideration. For larger repositories this produces a significant amount of overhead, slowing down several pages in Stash such as listing a repository's commits and displaying individual commits. This overhead is compounded when using a filesystem such as NFS for STASH_HOME or STASH_SHARED_HOME.

11 characters was chosen as the default length because it greatly increases the number of objects a repository needs to have in order to have a high chance of conflict on a given short SHA-1:

  • 7 characters requires only 20,000 objects in the repository to have a 50% chance of collision
  • 11 characters requires nearly 5,000,000 objects to have a 50% chance of collision

All URLs in Stash use full 40 character SHA-1s so, even if there is a conflict on a given 11 character short SHA-1, navigating Stash will not be affected. Longer short SHA-1s are used to reduce the likelihood that copying a short SHA-1 from the UI, since those are all the UI generally displays, and pasting it into a console window, or any other external Git tool, will fail due to ambiguity.

As part of making this change, ChangesetReader.FORMAT, part of stash-scm-git-common, was changed to eliminate the %h and %p elements. Any plugin code which just uses the ChangesetReader should not require a change, as long as they pass ChangesetReader.getFormat() to --format on their command, but any plugin code which directly references ChangesetReader.FORMAT and then does its own parsing will no longer work.

Stash 3.2

Home directory re-organization

As part of Stash 3.2, the home directory was re-organized. The following changes have been made:

  • The data/ directory has been moved to shared/data/
  • The config/ directory has moved to shared/config
  • The plugins/installed-plugins/ directory has moved to shared/plugins/installed-plugins/
  • The stash-config.properties file has moved to shared/stash-config.properties

The corresponding methods on ApplicationPropertiesService for these directories will return the new locations so plugins should be able to continue using these seamlessly.

Atlassian Plugin SDK compatibility

As a result of the home directory re-organization, Stash 3.2 requires Atlassian Plugin SDK 5.0.3 and above. Stash will fail to start if you attempt to run your plugin via the SDK in a previous version.

Asynchronous startup

Previously, Stash would initialize synchronously with the web container and be unable to service requests. In Stash 3.2 the startup was changed to be asynchronous, with Stash displaying progress of its initialization in the web UI.

Currently this can cause issues when trying to run integration tests against a Stash application as the Atlassian Plugin SDK will start running the tests before the application is fully initialized. In an upcoming release of the Atlassian Plugin SDK this will be fixed but as a workaround you can add the following configuration to your pom.xml to force Stash to initialize synchronously.

        <!-- Force Stash to start up synchronously -->

Atlassian SAL UserSettingsService

Stash now correctly implements the SAL UserSettingsService. Plugins can now use this service to retrieve and update settings associated with users. Prior to Stash 3.2 the service could be injected but it would not persist any settings.

Stash 3.0

Stash 3.0 is the first major release of Stash in over a year. All interfaces that were marked deprecated in Stash 2.11 and earlier have been removed completely. As a result, existing Stash 2.x plugins that use any deprecated interfaces are not be automatically compatible with Stash 3.0.

Deprecated Java APIs removed

Interfaces, classes, and methods in the Java API that were marked deprecated in Stash versions from 2.0 up to and including 2.11 have been removed.

Plugins that use any of these interfaces (which would have generated deprecation warnings when built against Stash 2.12) generally won't compile with Stash 3.0.

Precompiled plugins that used any of the deprecated interfaces will fail to install or run in Stash 3.0, typically with java.lang.NoSuchMethodError.

Updating your plugin for Stash 3.0 shouldn't be too difficult, as alternatives to most deprecated APIs have been documented in the Java API Reference for Stash 2.12.

The following classes and interfaces have been moved to new packages or superseded by newer alternatives.

A few classes and interfaces have also been removed altogether, with no equivalent alternative.

In addition, deprecated methods in existing classes and interfaces across the whole Stash API (too many to list here) have been removed.

Consult the Java API Reference for Stash 2.12 for details on the removed methods, and their alternatives in Stash 3.0.

Deprecated Web UI components removed

Stash 3.0 has also removed Web UI Components (JavaScript, Soy, and LESS) that were marked as deprecated in Stash versions 2.0 to 2.11 inclusive.

Plugins should not be depending on any of these deprecated components, as they do not include any Atlassian standard AUI components or published Stash extensions.

Nevertheless, if you want to verify that your plugin is not affected by the removal of deprecated Web UI APIs, try installing it in the latest 2.x release of Stash. All the removed interfaces were present in this release and annotated with @deprecated, so any use should result in deprecation warnings in the Developer Tools of your browser.

Internationalization (I18n)

Stash 3.0 now has internationalization (i18n) support, and includes three language packs: French, German and Japanese! Internationalizing your plugin for these languages is highly recommended to provide a consistent look and feel for customers in their own native language. The i18n API's for plugins have been available for some time, see Internationalizing your plugin for details.

Java 1.6

Stash 3.0 requires Java 1.7 (Oracle or OpenJDK) or higher, for both plugin development and runtime environment. Java 1.6 is no longer supported.

Scala 2.10

Stash 3.0 requires Scala 2.10 for plugin development. Scala 2.9 and earlier versions are no longer supported.

Help Soy functions deprecated

The Soy functions cav_help_url and cav_help_title for referencing help documentation are deprecated for removal in 4.0. Use stash_help_url and stash_help_title instead.

PullRequestLock and RepositoryLock moved to stash-api

The PullRequestLock and RepositoryLock which were previous in the stash-util module have been moved to the stash-api to facilitate the implementation of a LockService. The interfaces were moved verbatim and thus maintain their binary compatibility.

Stash 2.12

Changeset.getAuthor() and Person.getName() have always been expected to return a non-null value. Explicit @Nonnull annotations have now been added to those methods to explicitly document that expectation.

Scala 2.9 is deprecated for plugin development and will be removed in Stash 3.0. Scala 2.10 has been available to plugins since Stash 2.11.

Stash 2.11

Commit Comments

The HistoryService has been deprecated and renamed to CommitService. New methods have been added in CommitService which support commenting on commits. New REST resources have been added, similar to those used for pull requests, for adding, deleting and updating comments and for watching and unwatching commits.

  • To allow the new REST URLs to match the URL structure for pull requests, ref names are no longer supported by the commits REST resource (rest/api/latest/projects/KEY/repos/SLUG/commits/ID). Instead, you must provide a SHA1 to identify the commit. For example, rest/api/latest/projects/KEY/repos/SLUG/commits/refs/heads/master will no longer work. Instead, use the SHA1 for the latest commit on refs/heads/master, like rest/api/latest/projects/KEY/repos/SLUG/commits/5bad17727d52c17fa7f3a20ed433ebd2c1cdfa21.
  • rest/api/latest/projects/KEY/repos/SLUG/changes is now deprecated and will be removed in 3.0. Instead, use rest/api/latest/projects/KEY/repos/SLUG/commits/ID/changes, where ID is the value previously sent as ?until
  • rest/api/latest/projects/KEY/repos/SLUG/diff is now deprecated and will be removed in 3.0. Instead, use rest/api/latest/projects/KEY/repos/SLUG/commits/ID/diff, where ID is the value previously sent as ?until

The pullRequest context param provided to the stash.comments.actions and stash.comments.info web item locations for comments has been deprecated to be optional for 3.0. In 3.0, web-items for these locations should not always expect the pullRequest object as comments can also be made on commits.

Branching Model API

The Branch Model feature introduced in Stash 2.8 now offers Java and REST API, allowing plugin developers to:

  • Query whether a repository has a Branching Model associated with it
  • Get the Development and the Production branch
  • Get enabled branch types (Bugfix, Feature, Hotfix, Release)
  • Get a list of branches belonging to a given branch type
  • Classify a branch (get its category, if any)

Java API

The following interfaces are the entry point to the API and may be consumed from the branch-utils artifact:


As of Stash 2.11, the branch model for a given repository may be also queried via the REST API.

Stash 2.10

Log level when developing a plugin

When starting Stash with AMPS, the default log level of the Stash instance was changed from DEBUG to WARN.

Empty repository web panels

The stash.web.repository.empty location for web-panels has been deprecated and replaced with client-web-panels at the location stash.empty.repository.instructions. These client-web-panels will now receive the user preferred clone url (HTTP or SSH) as a context param and re-rendered when the user changes their clone URL preference.

Updating the base URL

Updating the base URL with ApplicationPropertiesService.setBaseUrl(URI) now requires SYS_ADMIN permission.

Streaming callbacks

The following callbacks have been added, extending existing callbacks:

These new interfaces make the callbacks more consistent with each other. They also introduce new onStart and onEnd methods which accept readily-extensible context and summary objects, respectively. The context provided to onStart offers insight into the shape of the command for which results are being streamed, with a summary of those results provided to onEnd. Some of these objects are simple placeholders, in this release, and will be fleshed out in future releases. Those changes, when they happen, will be backwards-compatible and will not require introducing new interfaces.

The existing interfaces are unchanged, so these new interfaces should not break any existing plugins. They are included in 2.10 to give plugin developers more time to update to the new interfaces. For each callback, an abstract base class is provided. Plugin developers should always extend from one of these base classes when implementing any callback. The base classes will make the callback implementations more resilient to future changes to the callbacks.

All of the new interfaces are deprecated, and will be folded back into their respective unversioned interfaces and removed in Stash 3.0. Plugin developers who extend their implementations from one of the base classes should not be affected by that change. Each new interface describes how its unversioned interface will change in the 3.0 release.

FileContentCallback.appendBlame(List) and FileContentCallback.onEndPage(Page)

In previous releases, FileContentCallback.appendBlame(List) was called after FileContentCallback.onEndPage(Page). Stash 2.10 introduces a non-backwards-compatible change where