diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala index 00f6755..e752916 100644 --- a/src/main/scala/app/RepositoryViewerController.scala +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -323,14 +323,10 @@ * Displays branches. */ get("/:owner/:repository/branches")(referrersOnly { repository => - using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git => - // retrieve latest update date of each branch - val branchInfo = repository.branchList.map { branchName => - val revCommit = git.log.add(git.getRepository.resolve(branchName)).setMaxCount(1).call.iterator.next - (branchName, revCommit.getCommitterIdent.getWhen) - } - repo.html.branches(branchInfo, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository) - } + val branches = JGitUtil.getBranches(repository.owner, repository.name, repository.repository.defaultBranch) + .sortBy(br => (br.mergeInfo.isEmpty, br.commitTime)) + .reverse + repo.html.branches(branches, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository) }) /** diff --git a/src/main/scala/util/JGitUtil.scala b/src/main/scala/util/JGitUtil.scala index b5e2e3b..bd730b5 100644 --- a/src/main/scala/util/JGitUtil.scala +++ b/src/main/scala/util/JGitUtil.scala @@ -133,6 +133,10 @@ */ case class SubmoduleInfo(name: String, path: String, url: String) + case class BranchMergeInfo(ahead: Int, behind: Int, isMerged: Boolean) + + case class BranchInfo(name: String, committerName: String, commitTime: Date, committerEmailAddress:String, mergeInfo: Option[BranchMergeInfo]) + /** * Returns RevCommit from the commit or tag id. * @@ -685,4 +689,43 @@ return git.log.add(startCommit).addPath(path).setMaxCount(1).call.iterator.next } + def getBranches(owner: String, name: String, defaultBranch: String): Seq[BranchInfo] = { + using(Git.open(getRepositoryDir(owner, name))){ git => + val repo = git.getRepository + val defaultObject = repo.resolve(defaultBranch) + git.branchList.call.asScala.map { ref => + val walk = new RevWalk(repo) + try{ + val defaultCommit = walk.parseCommit(defaultObject) + val branchName = ref.getName.stripPrefix("refs/heads/") + val branchCommit = if(branchName == defaultBranch){ + defaultCommit + }else{ + walk.parseCommit(ref.getObjectId) + } + val when = branchCommit.getCommitterIdent.getWhen + val committer = branchCommit.getCommitterIdent.getName + val committerEmail = branchCommit.getCommitterIdent.getEmailAddress + val mergeInfo = if(branchName==defaultBranch){ + None + }else{ + walk.reset() + walk.setRevFilter( RevFilter.MERGE_BASE ) + walk.markStart(branchCommit) + walk.markStart(defaultCommit) + val mergeBase = walk.next() + walk.reset() + walk.setRevFilter(RevFilter.ALL) + Some(BranchMergeInfo( + ahead = RevWalkUtils.count(walk, branchCommit, mergeBase), + behind = RevWalkUtils.count(walk, defaultCommit, mergeBase), + isMerged = walk.isMergedInto(branchCommit, defaultCommit))) + } + BranchInfo(branchName, committer, when, committerEmail, mergeInfo) + } finally { + walk.dispose(); + } + } + } + } } diff --git a/src/main/twirl/repo/branches.scala.html b/src/main/twirl/repo/branches.scala.html index 9857684..89ee98d 100644 --- a/src/main/twirl/repo/branches.scala.html +++ b/src/main/twirl/repo/branches.scala.html @@ -1,4 +1,4 @@ -@(branchInfo: Seq[(String, java.util.Date)], +@(branchInfo: Seq[util.JGitUtil.BranchInfo], hasWritePermission: Boolean, repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) @import context._ @@ -6,35 +6,46 @@ @html.main(s"${repository.owner}/${repository.name}", Some(repository)) { @html.menu("code", repository){

Branches

- - - - - - - - @branchInfo.map { case (branchName, latestUpdateDate) => +
BranchLast updateCompareDownload
+ - + + + + @branchInfo.map { branch => + - - - + }
- @branchName - @if(hasWritePermission && repository.repository.defaultBranch != branchName){ - Delete branch + All branches
+
+ @branch.mergeInfo.map{ info => + Compare + @if(hasWritePermission){ + + } + } +
+
+ @branch.name + + Updated @helper.html.datetimeago(branch.commitTime, false) + by @user(branch.committerName, branch.committerEmailAddress, "muted-link") + + +
+
+ @if(branch.mergeInfo.isEmpty){ + Default + }else{ + @branch.mergeInfo.map{ info => +
+
+
@info.ahead
+
@info.behind
+
+
+
+ } } -
- @helper.html.datetimeago(latestUpdateDate, false) - - @if(repository.repository.defaultBranch == branchName){ - Base branch - } else { - to @{repository.repository.defaultBranch} - } - - ZIP - TAR.GZ -
@@ -46,5 +57,63 @@ var branchName = $(e.target).data('name'); return confirm('Are you sure you want to remove the ' + branchName + ' branch?'); }); + $('*[data-toggle=tooltip]').tooltip(); }); - \ No newline at end of file + +