diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index b6b3fb5..1054149 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -117,6 +117,12 @@ diff: Option[String] ) + case class TagForm( + commitId: String, + tagName: String, + message: Option[String] + ) + val uploadForm = mapping( "branch" -> trim(label("Branch", text(required))), "path" -> trim(label("Path", text())), @@ -153,6 +159,12 @@ "diff" -> optional(text()) )(CommentForm.apply) + val tagForm = mapping( + "commitId" -> trim(label("Commit id", text(required))), + "tagName" -> trim(label("Tag name", text(required))), + "message" -> trim(label("Message", optional(text()))) + )(TagForm.apply) + /** * Returns converted HTML from Markdown for preview. */ @@ -542,7 +554,9 @@ repository, diffs, oldCommitId, - hasDeveloperRole(repository.owner, repository.name, context.loginAccount) + hasDeveloperRole(repository.owner, repository.name, context.loginAccount), + flash.get("info"), + flash.get("error") ) } } @@ -792,6 +806,29 @@ }) /** + * Displays the create tag dialog. + */ + get("/:owner/:repository/tag/:id")(writableUsersOnly { repository => + html.tag(params("id"), repository) + }) + + /** + * Creates a tag. + */ + post("/:owner/:repository/tag", tagForm)(writableUsersOnly { (form, repository) => + using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git => + JGitUtil.createTag(git, form.tagName, form.message, form.commitId) + } match { + case Right(message) => + flash += "info" -> message + redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}") + case Left(message) => + flash += "error" -> message + redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}") + } + }) + + /** * Creates a branch. */ post("/:owner/:repository/branches")(writableUsersOnly { repository => diff --git a/src/main/scala/gitbucket/core/util/JGitUtil.scala b/src/main/scala/gitbucket/core/util/JGitUtil.scala index 0381fdb..bef631a 100644 --- a/src/main/scala/gitbucket/core/util/JGitUtil.scala +++ b/src/main/scala/gitbucket/core/util/JGitUtil.scala @@ -23,12 +23,7 @@ import java.util.function.Consumer import org.cache2k.Cache2kBuilder -import org.eclipse.jgit.api.errors.{ - InvalidRefNameException, - JGitInternalException, - NoHeadException, - RefAlreadyExistsException -} +import org.eclipse.jgit.api.errors._ import org.eclipse.jgit.diff.{DiffEntry, DiffFormatter, RawTextComparator} import org.eclipse.jgit.dircache.DirCacheEntry import org.eclipse.jgit.util.io.DisabledOutputStream @@ -836,6 +831,25 @@ .find(_._1 != null) } + def createTag(git: Git, name: String, message: Option[String], commitId: String) = { + try { + val objectId: ObjectId = git.getRepository.resolve(commitId) + using(new RevWalk(git.getRepository)) { walk => + val tagCommand = git.tag().setName(name).setObjectId(walk.parseCommit(objectId)) + message.foreach { message => + tagCommand.setMessage(message) + } + tagCommand.call() + } + Right("Tag added.") + } catch { + case e: GitAPIException => Left("Sorry, some Git operation error occurs.") + case e: ConcurrentRefUpdateException => Left("Sorry some error occurs.") + case e: InvalidTagNameException => Left("Sorry, that name is invalid.") + case e: NoHeadException => Left("Sorry, this repo doesn't have HEAD reference") + } + } + def createBranch(git: Git, fromBranch: String, newBranch: String) = { try { git.branchCreate().setStartPoint(fromBranch).setName(newBranch).call() diff --git a/src/main/twirl/gitbucket/core/repo/commit.scala.html b/src/main/twirl/gitbucket/core/repo/commit.scala.html index 065a001..b0ebe76 100644 --- a/src/main/twirl/gitbucket/core/repo/commit.scala.html +++ b/src/main/twirl/gitbucket/core/repo/commit.scala.html @@ -6,17 +6,22 @@ repository: gitbucket.core.service.RepositoryService.RepositoryInfo, diffs: Seq[gitbucket.core.util.JGitUtil.DiffInfo], oldCommitId: Option[String], - hasWritePermission: Boolean)(implicit context: gitbucket.core.controller.Context) + hasWritePermission: Boolean, + info: Option[Any] = None, + error: Option[Any] = None)(implicit context: gitbucket.core.controller.Context) @import gitbucket.core.view.helpers @import gitbucket.core.view.helpers.RichHtmlSeq @import gitbucket.core.model._ @gitbucket.core.html.main(commit.shortMessage, Some(repository)){ - @gitbucket.core.html.menu("files", repository){ + @gitbucket.core.html.menu("files", repository, None, info, error){
-
+
Browse code + @if(hasWritePermission) { + Add tag + }
@helpers.link(commit.summary, repository)
@if(commit.description.isDefined){ diff --git a/src/main/twirl/gitbucket/core/repo/tag.scala.html b/src/main/twirl/gitbucket/core/repo/tag.scala.html new file mode 100644 index 0000000..6f40e9b --- /dev/null +++ b/src/main/twirl/gitbucket/core/repo/tag.scala.html @@ -0,0 +1,26 @@ +@(commitId: String, + repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context) +@import gitbucket.core.view.helpers +

+ Add tag +

+
+
+
+ + + +
+
+
+
+ + + +
+
+
+ + +
+