我想检查一个功能分支是否已经合并到我的主分支使用github api/Octokit。我还没有找到任何关于这个主题的文档或帖子。这可能吗?有人知道有关于这个话题的帖子吗?
这相当于git log master..my-cool-branch
使用Octokit -你想看看你的分支上是否有任何提交不在master
:
var head = "my-cool-branch";
var baseBranch = "master";
var compareBaseToHead = await client.Repository.Commit.Compare(owner, repo, baseBranch, head);
if (compareBaseToHead.TotalCommits == 0)
{
Console.WriteLine("Branch {0} has been merged into {1}", head, baseBranch);
}
else
{
Console.WriteLine("Branch {0} has NOT been merged into {1}", head, baseBranch);
}
我实际上刚刚完成了一个包含这种检查的脚本。我的脚本的总体目标是查看我们组织中的所有repos,并清理已合并的分支。脚本是用groovy编写的,并使用kohsuke的github-api java客户端。java客户端缺少一个特性,我有一个公开的PR。在合并PR并发布新版本之前,您将不得不忽略分支保护检查或做我所做的(自己拉出代码并使用添加的特性构建它)。
检查分支是否已经合并并且没有新的提交要合并的逻辑在cleanupBranches
方法中。基本上,我遍历给定回购的所有CLOSED pull request (PR)。如果合并了拉取请求,那么我将PR的头分支与回购的默认分支进行比较(并非所有的分支都命名为master
)。如果PR的头分支有0个未合并到默认分支的提交,则可以删除该分支。
我包含了我的整个脚本只是为了上下文。你会注意到我确实改变了一些配置属性的默认值。
@GrabResolver(name='binrepo', root='https://binrepo.myCompany.com')
@Grab(group='org.kohsuke', module='github-api', version='SNAPSHOT')
import org.kohsuke.github.*
// store some things here so they are available everywhere
class Config {
static Boolean doDelete = Boolean.valueOf(System.getProperty('branch.cleanup.doDelete', 'false'))
static String orgName = System.getProperty('branch.cleanup.gitOrgName', 'myOrg')
static String gitApiUrl = System.getProperty('branch.cleanup.gitApiUrl', 'https://git.myCompany.com/api/v3')
static String apiKey
}
def executeOnShell(String command, boolean log = false) {
File workingDir = new File(System.properties.'user.dir')
def process = new ProcessBuilder(addShellPrefix(command))
.directory(workingDir)
.redirectErrorStream(true)
.start()
if (log) {
process.inputStream.eachLine { println it }
}
process.waitFor();
}
def addShellPrefix(String command) {
def commandArray = new String[3]
commandArray[0] = "sh"
commandArray[1] = "-c"
commandArray[2] = command
return commandArray
}
def allRepos(GHOrganization org, String...repoPrefixes) {
println "Fetching all repositories under the ${Config.orgName} org that match prefix(es) ${repoPrefixes}"
return org.getRepositories().entrySet().findAll{ entry ->
if (repoPrefixes) {
return repoPrefixes.any{ prefix -> entry.key.startsWith(prefix) }
} else {
return true
}
}
}
def cleanupBranches(repo) {
def defaultBranchName = repo.getDefaultBranch()
def defaultBranch = repo.getBranch(defaultBranchName)
def deletedBranchNames = []
def branchesByName = repo.getBranches().entrySet().findAll{ !it.key.equals(defaultBranchName) && !it.value.isProtected() }.collectEntries{[it.key, it.value]}
def pullRequests = repo.queryPullRequests().base(defaultBranchName).state(GHIssueState.CLOSED).list().withPageSize(100).each{ pr ->
// loop thru all pull requests that have been closed and also merged
if (pr.isMerged()) {
def branch = branchesByName.get(pr.getHead().getRef())
if (branch) {
// the branch still exists and has been merged by this PR
// make sure it doesn't have any unmerged commits
def compare = repo.getCompare(defaultBranch, branch)
if (compare.getTotalCommits() == 0) {
// branch has been merged and there are 0 commits since merge. delete it
println "Branch ${repo.getName()}/${branch.getName()} has 0 commits not merged to ${defaultBranchName}. Delete it. PR ${pr.getNumber()} : ${pr.getTitle()}"
if (Config.doDelete) {
deleteBranch(repo, branch)
}
// remove from internal map of branches since the branch has now been deleted in git
branchesByName.remove(branch.getName())
deletedBranchNames.push "${repo.getName()}/${branch.getName()}"
}
}
}
}
return deletedBranchNames
}
def deleteBranch(repo, branch) {
// use a simple curl here because the kohsuke library way of doing it requires 2 api calls when just 1 will do here
String cmd = "curl -X DELETE -H "Authorization: token ${Config.apiKey}" ${Config.gitApiUrl}/repos/${Config.orgName}/${repo.getName()}/git/refs/heads/${branch.getName()}"
executeOnShell(cmd)
}
if (args.size() < 1) {
println "Usage: cleanupRepoBranches.groovy <oauthToken> <optionalRepo-name>"
System.exit(1)
}
Config.apiKey = args[0]
def branchesDeleted = []
def errors = []
GitHub github = GitHub.connectToEnterprise(Config.gitApiUrl, Config.apiKey)
if (args.size() > 1) {
String repoName = args[1]
GHRepository repo = github.getRepository("${Config.orgName}/${repoName}")
branchesDeleted = cleanupBranches(repo)
} else {
def repoPrefixes = System.getProperty('branch.cleanup.repoPrefixes', 'pref-,pref2-').split(',')
def answer = System.console().readLine "You have not specified a repoName. If you proceed, this script will list ${Config.doDelete ? 'and delete ' : ''}all branches with a merged pull request and 0 commits left to merge for all repos starting with ${repoPrefixes.join(', ')} in the ${Config.orgName} org. Are you sure? (y/n) "
if (answer == 'y') {
println 'ok! here we go!'
allRepos(github.getOrganization(Config.orgName), repoPrefixes).each { entry ->
try {
branchesDeleted += cleanupBranches(entry.value)
} catch (Exception e) {
errors.push([ message: "Error processing branches for ${entry.key} repo", ex: e ])
}
}
}
}
println "${branchesDeleted.size()} Branches deleted..."
branchesDeleted.each{ branch -> println branch }
println "${errors.size()} errors..."
errors.each{ error ->
println error.message
error.ex.printStackTrace()
println
}
我相信您可以从拉取请求中获得分支,然后,在合并后检查拉取请求是否已合并。更多信息请访问:
https://developer.github.com/v3/pulls/get-if-a-pull-request-has-been-merged