diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala index 18a9f3f..5b5b11b 100644 --- a/src/main/scala/app/RepositoryViewerController.scala +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -114,7 +114,7 @@ repo.html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository, logs.splitWith{ (commit1, commit2) => view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime) - }, page, hasNext) + }, page, hasNext, hasWritePermission(repository.owner, repository.name, context.loginAccount)) case Left(_) => NotFound } } @@ -242,6 +242,24 @@ }) /** + * Creates a branch. + */ + post("/:owner/:repository/branches")(collaboratorsOnly { repository => + val newBranchName = params.getOrElse("new", halt(400)) + val fromBranchName = params.getOrElse("from", halt(400)) + using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git => + JGitUtil.createBranch(git, fromBranchName, newBranchName) + } match { + case Right(message) => + flash += "info" -> message + redirect(s"/${repository.owner}/${repository.name}/tree/${StringUtil.urlEncode(newBranchName).replace("%2F", "/")}") + case Left(message) => + flash += "error" -> message + redirect(s"/${repository.owner}/${repository.name}/tree/${fromBranchName}") + } + }) + + /** * Deletes branch. */ get("/:owner/:repository/delete/*")(collaboratorsOnly { repository => @@ -333,7 +351,8 @@ repo.html.files(revision, repository, if(path == ".") Nil else path.split("/").toList, // current path new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit - files, readme, hasWritePermission(repository.owner, repository.name, context.loginAccount)) + files, readme, hasWritePermission(repository.owner, repository.name, context.loginAccount), + flash.get("info"), flash.get("error")) } } getOrElse NotFound } diff --git a/src/main/scala/util/JGitUtil.scala b/src/main/scala/util/JGitUtil.scala index 0e0493d..5ea43a3 100644 --- a/src/main/scala/util/JGitUtil.scala +++ b/src/main/scala/util/JGitUtil.scala @@ -14,7 +14,7 @@ import org.eclipse.jgit.diff.DiffEntry.ChangeType import org.eclipse.jgit.errors.{ConfigInvalidException, MissingObjectException} import java.util.Date -import org.eclipse.jgit.api.errors.NoHeadException +import org.eclipse.jgit.api.errors.{JGitInternalException, InvalidRefNameException, RefAlreadyExistsException, NoHeadException} import service.RepositoryService import org.eclipse.jgit.dircache.DirCacheEntry import org.slf4j.LoggerFactory @@ -507,6 +507,17 @@ }.find(_._1 != null) } + def createBranch(git: Git, fromBranch: String, newBranch: String) = { + try { + git.branchCreate().setStartPoint(fromBranch).setName(newBranch).call() + Right("Branch created.") + } catch { + case e: RefAlreadyExistsException => Left("Sorry, that branch already exists.") + // JGitInternalException occurs when new branch name is 'a' and the branch whose name is 'a/*' exists. + case _: InvalidRefNameException | _: JGitInternalException => Left("Sorry, that name is invalid.") + } + } + def createDirCacheEntry(path: String, mode: FileMode, objectId: ObjectId): DirCacheEntry = { val entry = new DirCacheEntry(path) entry.setFileMode(mode) diff --git a/src/main/twirl/helper/branchcontrol.scala.html b/src/main/twirl/helper/branchcontrol.scala.html new file mode 100644 index 0000000..5381688 --- /dev/null +++ b/src/main/twirl/helper/branchcontrol.scala.html @@ -0,0 +1,62 @@ +@(branch: String = "", + repository: service.RepositoryService.RepositoryInfo, + hasWritePermission: Boolean)(body: Html)(implicit context: app.Context) +@import context._ +@import view.helpers._ +@helper.html.dropdown( + value = if(branch.length == 40) branch.substring(0, 10) else branch, + prefix = if(branch.length == 40) "tree" else if(repository.branchList.contains(branch)) "branch" else "tree", + mini = true +) { +