When creating a pull request, how do you ensure the source branch is branched from destination head?

Mark Ingram September 18, 2015

Our workflow requires us to rebase our branches, before we create a pull request, in order to preserve the linear merge graph. It would be useful to be able to automatically decline a pull request (or as a minimum present some sort of warning, or notification) if a pull request has been accepted to upstream, since your original branch or last rebase. Is there any built in feature or plugin via the marketplace that supports this?

 

4 answers

1 vote
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 18, 2015

Hi Mark... you want a mergecheck. I'm surprised this isn't already in the plugin, but it doesn't seem to be.

You can add a custom merge check with the following script:

import com.onresolve.scriptrunner.canned.stash.events.BlockOutOfDatePullRequests
 
def pullRequest = mergeRequest.pullRequest
def aheadBehindInfo = new BlockOutOfDatePullRequests().isPullRequestUpToDate(pullRequest)
 
if (! aheadBehindInfo.alreadyRebased) {
    mergeRequest.veto("Can't merge because out of date", "Please rebase then have another go...")
}

which looks like:

image2015-9-18 17:3:10.png

It can be difficult though to rebase if you've already merged to your feature branch from the target. But I guess once people have been bitten once they'll rebase rather than merge...

There is more chat about this kind of thing here: http://www.adaptavist.com/w/inside-adaptavists-stash-pull-request-workflow/

 

 

 

Mark Ingram September 20, 2015

I think this is exactly what I'm after! I'll check it out and accept the answer if it works. Thanks.

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 20, 2015

No worries, get in touch with us via https://productsupport.adaptavist.com/servicedesk/customer/portal/3 if you need some hands-on help making it work.

Peguiron Ernst, Mathias September 20, 2018

Hello,

I tried the above but the line :

import com.onresolve.scriptrunner.canned.stash.events.BlockOutOfDatePullRequests

 Throws an error "unable to resolve class "com.onresolve.scriptrunner.canned.stash.events.BlockOutOfDatePullRequests"

I'm on Bitbucket server 5.12.1 and Scriptrunner 5.4.18

tomasz_sobczyk_cog January 7, 2019

I'm looking for something like this as well. We don't exactly force everyone to re-base / simply merge so I'm rather after a plain information if there are any commits in master that haven't landed in the feature branch - if yes - then merging should be blocked.

Like Erik Baty likes this
tomasz_sobczyk_cog January 7, 2019

@JamieA Can you help?

Jaideep Padhye March 9, 2019

I'd to change the request code to 

 

 

import com.onresolve.scriptrunner.canned.bitbucket.events.BlockOutOfDatePullRequests

def pullRequest = mergeRequest.pullRequest
def aheadBehindInfo = new BlockOutOfDatePullRequests().isPullRequestUpToDate(pullRequest)

if (! aheadBehindInfo.alreadyRebased) {
mergeRequest.veto("Can't merge because needs rebase", "Please rebase then have another go...")
}

 

Jaideep Padhye March 9, 2019

Fails with an error though:

<pre>org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script117.groovy: 4: [Static type checking] - You tried to call a method which is not allowed: com.onresolve.scriptrunner.canned.bitbucket.events.BlockOutOfDatePullRequests#<init>() @ line 4, column 23. def aheadBehindInfo = new BlockOutOfDatePullRequests().isPullRequestUpToDate(pullRequest) ^ Script117.groovy: 6: [Static type checking] - Property is not allowed: com.onresolve.scriptrunner.canned.bitbucket.pullrequests.AheadBehindInfo#alreadyRebased @ line 6, column 7. if (! aheadBehindInfo.alreadyRebased) { ^ 2 errors </pre>
Jaideep Padhye March 9, 2019

Looks like 

BlockOutOfDatePullRequests

class has been deprecated. https://docs.atlassian.com/bitbucket-server/javadoc/6.1.1/api/reference/classes.html#letter_B

1 vote
Mark McCormack _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 18, 2015

@Mark Ingram - there is a paid add-on in the Marketplace called ScriptRunner for Stash that supports this. The documentation outlines how to block the creation of out of date Pull Requests. I think that might meet your needs.

Mark Ingram September 18, 2015

Thanks, that's nearly exactly what I need, except we would like to be able to add multiple pull requests, but just block the merging if the request is out of date. With the solution you provided, you can only create 1 pull request at once. Is this possible?

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 18, 2015

I'm not really sure what you mean... you can always only create one PR per source and target branch combination. I would recommend using this policy, along with my answer. It's better to get people to rebase at the time they try to create the PR, otherwise they may well not even notice it's out of date. But also you need the merge check in my answer because it can go out of date. Ideally you want to notify them when it becomes out of date, as the person merging is probably not the person that can rebase it.

0 votes
dmitry October 19, 2020

here is what I came up with:

import com.atlassian.bitbucket.commit.CommitsBetweenRequest
import com.atlassian.bitbucket.commit.Commit
import com.atlassian.bitbucket.util.PageRequestImpl
import com.atlassian.bitbucket.util.Page
import com.atlassian.bitbucket.commit.CommitService
import com.atlassian.sal.api.component.ComponentLocator

def pageLimit = com.atlassian.bitbucket.util.PageRequest.MAX_PAGE_LIMIT

def CommitService commitService = ComponentLocator.getComponent(CommitService)

def pullRequest = mergeRequest.pullRequest

def toRefLatestCommit = pullRequest.toRef.getLatestCommit()

CommitsBetweenRequest.Builder builder = new CommitsBetweenRequest.Builder(mergeRequest.pullRequest);
CommitsBetweenRequest cbr = builder.build();
Page<Commit> cs = commitService.getCommitsBetween(cbr, new PageRequestImpl(0, pageLimit ))

def isUpToDate = cs.getValues().any{c -> c.getParents().any { p -> p.getId() == toRefLatestCommit} }

if (!isUpToDate) {
mergeRequest.veto("Can't merge because needs rebase", "Please rebase first.)
}
0 votes
Jaideep Padhye March 9, 2019

@JamieA  I'm still looking for the answer too. Could you please suggest how to get this working.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events