mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-01-07 08:02:14 +01:00
Merge pull request #1790 from gitbucket/copy-repository
Create new repository from existing git repository
This commit is contained in:
@@ -2,7 +2,7 @@ package gitbucket.core.controller
|
||||
|
||||
import gitbucket.core.account.html
|
||||
import gitbucket.core.helper
|
||||
import gitbucket.core.model.{AccountWebHook, GroupMember, RepositoryWebHook, RepositoryWebHookEvent, Role, WebHook, WebHookContentType}
|
||||
import gitbucket.core.model.{AccountWebHook, GroupMember, RepositoryWebHook, Role, WebHook, WebHookContentType}
|
||||
import gitbucket.core.plugin.PluginRegistry
|
||||
import gitbucket.core.service._
|
||||
import gitbucket.core.service.WebHookService._
|
||||
@@ -12,7 +12,6 @@ import gitbucket.core.util.Directory._
|
||||
import gitbucket.core.util.Implicits._
|
||||
import gitbucket.core.util.StringUtil._
|
||||
import gitbucket.core.util._
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.scalatra.i18n.Messages
|
||||
import org.scalatra.BadRequest
|
||||
import org.scalatra.forms._
|
||||
@@ -87,15 +86,16 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
"clearImage" -> trim(label("Clear image" ,boolean()))
|
||||
)(EditGroupForm.apply)
|
||||
|
||||
case class RepositoryCreationForm(owner: String, name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean)
|
||||
case class RepositoryCreationForm(owner: String, name: String, description: Option[String], isPrivate: Boolean, initOption: String, sourceUrl: Option[String])
|
||||
case class ForkRepositoryForm(owner: String, name: String)
|
||||
|
||||
val newRepositoryForm = mapping(
|
||||
"owner" -> trim(label("Owner" , text(required, maxlength(100), identifier, existsAccount))),
|
||||
"name" -> trim(label("Repository name", text(required, maxlength(100), repository, uniqueRepository))),
|
||||
"description" -> trim(label("Description" , optional(text()))),
|
||||
"isPrivate" -> trim(label("Repository Type", boolean())),
|
||||
"createReadme" -> trim(label("Create README" , boolean()))
|
||||
"owner" -> trim(label("Owner", text(required, maxlength(100), identifier, existsAccount))),
|
||||
"name" -> trim(label("Repository name", text(required, maxlength(100), repository, uniqueRepository))),
|
||||
"description" -> trim(label("Description", optional(text()))),
|
||||
"isPrivate" -> trim(label("Repository Type", boolean())),
|
||||
"initOption" -> trim(label("Initialize option", text(required))),
|
||||
"sourceUrl" -> trim(label("Source URL", optionalRequired(_.value("initOption") == "COPY", text())))
|
||||
)(RepositoryCreationForm.apply)
|
||||
|
||||
val forkRepositoryForm = mapping(
|
||||
@@ -461,7 +461,6 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
|
||||
get("/:groupName/_editgroup")(managersOnly {
|
||||
defining(params("groupName")){ groupName =>
|
||||
// TODO Don't use Option.get
|
||||
getAccountByUserName(groupName, true).map { account =>
|
||||
html.editgroup(account, getGroupMembers(groupName), flash.get("info"))
|
||||
} getOrElse NotFound()
|
||||
@@ -528,11 +527,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
post("/new", newRepositoryForm)(usersOnly { form =>
|
||||
LockUtil.lock(s"${form.owner}/${form.name}"){
|
||||
if(getRepository(form.owner, form.name).isEmpty){
|
||||
// Create the repository
|
||||
createRepository(context.loginAccount.get, form.owner, form.name, form.description, form.isPrivate, form.createReadme)
|
||||
|
||||
// Call hooks
|
||||
PluginRegistry().getRepositoryHooks.foreach(_.created(form.owner, form.name))
|
||||
createRepository(context.loginAccount.get, form.owner, form.name, form.description, form.isPrivate, form.initOption, form.sourceUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,66 +561,15 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
val loginUserName = loginAccount.userName
|
||||
val accountName = form.accountName
|
||||
|
||||
LockUtil.lock(s"${accountName}/${repository.name}"){
|
||||
if(getRepository(accountName, repository.name).isDefined ||
|
||||
(accountName != loginUserName && !getGroupsByUserName(loginUserName).contains(accountName))){
|
||||
// redirect to the repository if repository already exists
|
||||
redirect(s"/${accountName}/${repository.name}")
|
||||
} else {
|
||||
// Insert to the database at first
|
||||
val originUserName = repository.repository.originUserName.getOrElse(repository.owner)
|
||||
val originRepositoryName = repository.repository.originRepositoryName.getOrElse(repository.name)
|
||||
|
||||
insertRepository(
|
||||
repositoryName = repository.name,
|
||||
userName = accountName,
|
||||
description = repository.repository.description,
|
||||
isPrivate = repository.repository.isPrivate,
|
||||
originRepositoryName = Some(originRepositoryName),
|
||||
originUserName = Some(originUserName),
|
||||
parentRepositoryName = Some(repository.name),
|
||||
parentUserName = Some(repository.owner)
|
||||
)
|
||||
|
||||
// Set default collaborators for the private fork
|
||||
if(repository.repository.isPrivate){
|
||||
// Copy collaborators from the source repository
|
||||
getCollaborators(repository.owner, repository.name).foreach { case (collaborator, _) =>
|
||||
addCollaborator(accountName, repository.name, collaborator.collaboratorName, collaborator.role)
|
||||
}
|
||||
// Register an owner of the source repository as a collaborator
|
||||
addCollaborator(accountName, repository.name, repository.owner, Role.ADMIN.name)
|
||||
}
|
||||
|
||||
// Insert default labels
|
||||
insertDefaultLabels(accountName, repository.name)
|
||||
// Insert default priorities
|
||||
insertDefaultPriorities(accountName, repository.name)
|
||||
|
||||
// clone repository actually
|
||||
JGitUtil.cloneRepository(
|
||||
getRepositoryDir(repository.owner, repository.name),
|
||||
FileUtil.deleteIfExists(getRepositoryDir(accountName, repository.name)))
|
||||
|
||||
// Create Wiki repository
|
||||
JGitUtil.cloneRepository(getWikiRepositoryDir(repository.owner, repository.name),
|
||||
FileUtil.deleteIfExists(getWikiRepositoryDir(accountName, repository.name)))
|
||||
|
||||
// Copy LFS files
|
||||
val lfsDir = getLfsDir(repository.owner, repository.name)
|
||||
if(lfsDir.exists){
|
||||
FileUtils.copyDirectory(lfsDir, FileUtil.deleteIfExists(getLfsDir(accountName, repository.name)))
|
||||
}
|
||||
|
||||
// Record activity
|
||||
recordForkActivity(repository.owner, repository.name, loginUserName, accountName)
|
||||
|
||||
// Call hooks
|
||||
PluginRegistry().getRepositoryHooks.foreach(_.forked(repository.owner, accountName, repository.name))
|
||||
|
||||
// redirect to the repository
|
||||
redirect(s"/${accountName}/${repository.name}")
|
||||
}
|
||||
if (getRepository(accountName, repository.name).isDefined ||
|
||||
(accountName != loginUserName && !getGroupsByUserName(loginUserName).contains(accountName))) {
|
||||
// redirect to the repository if repository already exists
|
||||
redirect(s"/${accountName}/${repository.name}")
|
||||
} else {
|
||||
// fork repository asynchronously
|
||||
forkRepository(accountName, repository, loginUserName)
|
||||
// redirect to the repository
|
||||
redirect(s"/${accountName}/${repository.name}")
|
||||
}
|
||||
} else BadRequest()
|
||||
})
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.eclipse.jgit.revwalk.RevWalk
|
||||
import org.scalatra.{Created, NoContent, UnprocessableEntity}
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class ApiController extends ApiControllerBase
|
||||
with RepositoryService
|
||||
@@ -249,7 +251,8 @@ trait ApiControllerBase extends ControllerBase {
|
||||
} yield {
|
||||
LockUtil.lock(s"${owner}/${data.name}") {
|
||||
if(getRepository(owner, data.name).isEmpty){
|
||||
createRepository(context.loginAccount.get, owner, data.name, data.description, data.`private`, data.auto_init)
|
||||
val f = createRepository(context.loginAccount.get, owner, data.name, data.description, data.`private`, data.auto_init)
|
||||
Await.result(f, Duration.Inf)
|
||||
val repository = getRepository(owner, data.name).get
|
||||
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(owner).get)))
|
||||
} else {
|
||||
@@ -273,7 +276,8 @@ trait ApiControllerBase extends ControllerBase {
|
||||
} yield {
|
||||
LockUtil.lock(s"${groupName}/${data.name}") {
|
||||
if(getRepository(groupName, data.name).isEmpty){
|
||||
createRepository(context.loginAccount.get, groupName, data.name, data.description, data.`private`, data.auto_init)
|
||||
val f = createRepository(context.loginAccount.get, groupName, data.name, data.description, data.`private`, data.auto_init)
|
||||
Await.result(f, Duration.Inf)
|
||||
val repository = getRepository(groupName, data.name).get
|
||||
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(groupName).get)))
|
||||
} else {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.eclipse.jgit.dircache.{DirCache, DirCacheBuilder}
|
||||
import org.eclipse.jgit.errors.MissingObjectException
|
||||
import org.eclipse.jgit.lib._
|
||||
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
|
||||
import org.json4s.jackson.Serialization
|
||||
import org.scalatra._
|
||||
import org.scalatra.i18n.Messages
|
||||
|
||||
@@ -148,14 +149,31 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
* Displays the file list of the repository root and the default branch.
|
||||
*/
|
||||
get("/:owner/:repository") {
|
||||
params.get("go-get") match {
|
||||
case Some("1") => defining(request.paths){ paths =>
|
||||
getRepository(paths(0), paths(1)).map(gitbucket.core.html.goget(_))getOrElse NotFound()
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
if (RepositoryCreationService.isCreating(owner, repository)) {
|
||||
gitbucket.core.repo.html.creating(owner, repository)
|
||||
} else {
|
||||
params.get("go-get") match {
|
||||
case Some("1") => defining(request.paths) { paths =>
|
||||
getRepository(owner, repository).map(gitbucket.core.html.goget(_)) getOrElse NotFound()
|
||||
}
|
||||
case _ => referrersOnly(fileList(_))
|
||||
}
|
||||
case _ => referrersOnly(fileList(_))
|
||||
}
|
||||
}
|
||||
|
||||
ajaxGet("/:owner/:repository/creating") {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
contentType = formats("json")
|
||||
Serialization.write(Map(
|
||||
"creating" -> RepositoryCreationService.isCreating(owner, repository),
|
||||
"error" -> RepositoryCreationService.getCreationError(owner, repository)
|
||||
))
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the file list of the specified path and branch.
|
||||
*/
|
||||
@@ -403,7 +421,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
contentType = formats("json")
|
||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
val last = git.log.add(git.getRepository.resolve(id)).addPath(path).setMaxCount(1).call.iterator.next.name
|
||||
Map(
|
||||
Serialization.write(Map(
|
||||
"root" -> s"${context.baseUrl}/${repository.owner}/${repository.name}",
|
||||
"id" -> id,
|
||||
"path" -> path,
|
||||
@@ -418,8 +436,9 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
"prevPath" -> blame.prevPath,
|
||||
"commited" -> blame.commitTime.getTime,
|
||||
"message" -> blame.message,
|
||||
"lines" -> blame.lines)
|
||||
})
|
||||
"lines" -> blame.lines
|
||||
)
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,71 +1,206 @@
|
||||
package gitbucket.core.service
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||
import gitbucket.core.util.SyntaxSugars._
|
||||
import gitbucket.core.util.Directory._
|
||||
import gitbucket.core.util.JGitUtil
|
||||
import gitbucket.core.model.Account
|
||||
import gitbucket.core.util.{FileUtil, JGitUtil, LockUtil}
|
||||
import gitbucket.core.model.{Account, Role}
|
||||
import gitbucket.core.plugin.PluginRegistry
|
||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||
import gitbucket.core.servlet.Database
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.dircache.DirCache
|
||||
import org.eclipse.jgit.lib.{FileMode, Constants}
|
||||
import org.eclipse.jgit.lib.{Constants, FileMode}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
|
||||
object RepositoryCreationService {
|
||||
|
||||
private val Creating = new ConcurrentHashMap[String, Option[String]]()
|
||||
|
||||
def isCreating(owner: String, repository: String): Boolean = {
|
||||
Option(Creating.get(s"${owner}/${repository}")).map(_.isEmpty).getOrElse(false)
|
||||
}
|
||||
|
||||
def startCreation(owner: String, repository: String): Unit = {
|
||||
Creating.put(s"${owner}/${repository}", None)
|
||||
}
|
||||
|
||||
def endCreation(owner: String, repository: String, error: Option[String]): Unit = {
|
||||
error match {
|
||||
case None => Creating.remove(s"${owner}/${repository}")
|
||||
case Some(error) => Creating.put(s"${owner}/${repository}", Some(error))
|
||||
}
|
||||
}
|
||||
|
||||
def getCreationError(owner: String, repository: String): Option[String] = {
|
||||
Option(Creating.remove(s"${owner}/${repository}")).getOrElse(None)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trait RepositoryCreationService {
|
||||
self: AccountService with RepositoryService with LabelsService with WikiService with ActivityService with PrioritiesService =>
|
||||
|
||||
def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean)
|
||||
(implicit s: Session) {
|
||||
val ownerAccount = getAccountByUserName(owner).get
|
||||
val loginUserName = loginAccount.userName
|
||||
def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String],
|
||||
isPrivate: Boolean, createReadme: Boolean): Future[Unit] = {
|
||||
createRepository(loginAccount, owner, name, description, isPrivate, if (createReadme) "README" else "EMPTY", None)
|
||||
}
|
||||
|
||||
// Insert to the database at first
|
||||
insertRepository(name, owner, description, isPrivate)
|
||||
def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String],
|
||||
isPrivate: Boolean, initOption: String, sourceUrl: Option[String]): Future[Unit] = Future {
|
||||
RepositoryCreationService.startCreation(owner, name)
|
||||
try {
|
||||
Database() withTransaction { implicit session =>
|
||||
val ownerAccount = getAccountByUserName(owner).get
|
||||
val loginUserName = loginAccount.userName
|
||||
|
||||
// // Add collaborators for group repository
|
||||
// if(ownerAccount.isGroupAccount){
|
||||
// getGroupMembers(owner).foreach { member =>
|
||||
// addCollaborator(owner, name, member.userName)
|
||||
// }
|
||||
// }
|
||||
val copyRepositoryDir = if (initOption == "COPY") {
|
||||
sourceUrl.flatMap { url =>
|
||||
val dir = Files.createTempDirectory(s"gitbucket-${owner}-${name}").toFile
|
||||
Git.cloneRepository().setBare(true).setURI(url).setDirectory(dir).setCloneAllBranches(true).call()
|
||||
Some(dir)
|
||||
}
|
||||
} else None
|
||||
|
||||
// Insert default labels
|
||||
insertDefaultLabels(owner, name)
|
||||
|
||||
// Insert default priorities
|
||||
insertDefaultPriorities(owner, name)
|
||||
// Insert to the database at first
|
||||
insertRepository(name, owner, description, isPrivate)
|
||||
|
||||
// Create the actual repository
|
||||
val gitdir = getRepositoryDir(owner, name)
|
||||
JGitUtil.initRepository(gitdir)
|
||||
// // Add collaborators for group repository
|
||||
// if(ownerAccount.isGroupAccount){
|
||||
// getGroupMembers(owner).foreach { member =>
|
||||
// addCollaborator(owner, name, member.userName)
|
||||
// }
|
||||
// }
|
||||
|
||||
if(createReadme){
|
||||
using(Git.open(gitdir)){ git =>
|
||||
val builder = DirCache.newInCore.builder()
|
||||
val inserter = git.getRepository.newObjectInserter()
|
||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||
val content = if(description.nonEmpty){
|
||||
name + "\n" +
|
||||
"===============\n" +
|
||||
"\n" +
|
||||
description.get
|
||||
} else {
|
||||
name + "\n" +
|
||||
"===============\n"
|
||||
// Insert default labels
|
||||
insertDefaultLabels(owner, name)
|
||||
|
||||
// Insert default priorities
|
||||
insertDefaultPriorities(owner, name)
|
||||
|
||||
// Create the actual repository
|
||||
val gitdir = getRepositoryDir(owner, name)
|
||||
JGitUtil.initRepository(gitdir)
|
||||
|
||||
if (initOption == "README") {
|
||||
using(Git.open(gitdir)) { git =>
|
||||
val builder = DirCache.newInCore.builder()
|
||||
val inserter = git.getRepository.newObjectInserter()
|
||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||
val content = if (description.nonEmpty) {
|
||||
name + "\n" +
|
||||
"===============\n" +
|
||||
"\n" +
|
||||
description.get
|
||||
} else {
|
||||
name + "\n" +
|
||||
"===============\n"
|
||||
}
|
||||
|
||||
builder.add(JGitUtil.createDirCacheEntry("README.md", FileMode.REGULAR_FILE,
|
||||
inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
|
||||
builder.finish()
|
||||
|
||||
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
|
||||
Constants.HEAD, loginAccount.fullName, loginAccount.mailAddress, "Initial commit")
|
||||
}
|
||||
}
|
||||
|
||||
builder.add(JGitUtil.createDirCacheEntry("README.md", FileMode.REGULAR_FILE,
|
||||
inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
|
||||
builder.finish()
|
||||
copyRepositoryDir.foreach { dir =>
|
||||
try {
|
||||
using(Git.open(dir)) { git =>
|
||||
git.push().setRemote(gitdir.toURI.toString).setPushAll().setPushTags().call()
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteQuietly(dir)
|
||||
}
|
||||
}
|
||||
|
||||
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
|
||||
Constants.HEAD, loginAccount.fullName, loginAccount.mailAddress, "Initial commit")
|
||||
// Create Wiki repository
|
||||
createWikiRepository(loginAccount, owner, name)
|
||||
|
||||
// Record activity
|
||||
recordCreateRepositoryActivity(owner, name, loginUserName)
|
||||
|
||||
// Call hooks
|
||||
PluginRegistry().getRepositoryHooks.foreach(_.created(owner, name))
|
||||
}
|
||||
|
||||
RepositoryCreationService.endCreation(owner, name, None)
|
||||
|
||||
} catch {
|
||||
case ex: Exception => RepositoryCreationService.endCreation(owner, name, Some(ex.toString))
|
||||
}
|
||||
}
|
||||
|
||||
// Create Wiki repository
|
||||
createWikiRepository(loginAccount, owner, name)
|
||||
def forkRepository(accountName: String, repository: RepositoryInfo, loginUserName: String): Future[Unit] = Future {
|
||||
RepositoryCreationService.startCreation(accountName, repository.name)
|
||||
try {
|
||||
LockUtil.lock(s"${accountName}/${repository.name}") {
|
||||
Database() withTransaction { implicit session =>
|
||||
val originUserName = repository.repository.originUserName.getOrElse(repository.owner)
|
||||
val originRepositoryName = repository.repository.originRepositoryName.getOrElse(repository.name)
|
||||
|
||||
// Record activity
|
||||
recordCreateRepositoryActivity(owner, name, loginUserName)
|
||||
insertRepository(
|
||||
repositoryName = repository.name,
|
||||
userName = accountName,
|
||||
description = repository.repository.description,
|
||||
isPrivate = repository.repository.isPrivate,
|
||||
originRepositoryName = Some(originRepositoryName),
|
||||
originUserName = Some(originUserName),
|
||||
parentRepositoryName = Some(repository.name),
|
||||
parentUserName = Some(repository.owner)
|
||||
)
|
||||
|
||||
// Set default collaborators for the private fork
|
||||
if (repository.repository.isPrivate) {
|
||||
// Copy collaborators from the source repository
|
||||
getCollaborators(repository.owner, repository.name).foreach { case (collaborator, _) =>
|
||||
addCollaborator(accountName, repository.name, collaborator.collaboratorName, collaborator.role)
|
||||
}
|
||||
// Register an owner of the source repository as a collaborator
|
||||
addCollaborator(accountName, repository.name, repository.owner, Role.ADMIN.name)
|
||||
}
|
||||
|
||||
// Insert default labels
|
||||
insertDefaultLabels(accountName, repository.name)
|
||||
// Insert default priorities
|
||||
insertDefaultPriorities(accountName, repository.name)
|
||||
|
||||
// clone repository actually
|
||||
JGitUtil.cloneRepository(
|
||||
getRepositoryDir(repository.owner, repository.name),
|
||||
FileUtil.deleteIfExists(getRepositoryDir(accountName, repository.name)))
|
||||
|
||||
// Create Wiki repository
|
||||
JGitUtil.cloneRepository(getWikiRepositoryDir(repository.owner, repository.name),
|
||||
FileUtil.deleteIfExists(getWikiRepositoryDir(accountName, repository.name)))
|
||||
|
||||
// Copy LFS files
|
||||
val lfsDir = getLfsDir(repository.owner, repository.name)
|
||||
if (lfsDir.exists) {
|
||||
FileUtils.copyDirectory(lfsDir, FileUtil.deleteIfExists(getLfsDir(accountName, repository.name)))
|
||||
}
|
||||
|
||||
// Record activity
|
||||
recordForkActivity(repository.owner, repository.name, loginUserName, accountName)
|
||||
|
||||
// Call hooks
|
||||
PluginRegistry().getRepositoryHooks.foreach(_.forked(repository.owner, accountName, repository.name))
|
||||
|
||||
RepositoryCreationService.endCreation(accountName, repository.name, None)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
case ex: Exception => RepositoryCreationService.endCreation(accountName, repository.name, Some(ex.toString))
|
||||
}
|
||||
}
|
||||
|
||||
def insertDefaultLabels(userName: String, repositoryName: String)(implicit s: Session): Unit = {
|
||||
|
||||
@@ -39,7 +39,7 @@ isCreateRepoOptionPublic: Boolean)(implicit context: gitbucket.core.controller.C
|
||||
</fieldset>
|
||||
<fieldset class="form-group">
|
||||
<label for="description" class="strong">Description (optional):</label>
|
||||
<input type="text" name="description" id="description" class="form-control" style="width: 95%;"/>
|
||||
<input type="text" name="description" id="description" class="form-control" />
|
||||
</fieldset>
|
||||
<fieldset class="border-top">
|
||||
<label class="radio">
|
||||
@@ -58,14 +58,30 @@ isCreateRepoOptionPublic: Boolean)(implicit context: gitbucket.core.controller.C
|
||||
</label>
|
||||
</fieldset>
|
||||
<fieldset class="border-top">
|
||||
<label for="createReadme" class="checkbox">
|
||||
<input type="checkbox" name="createReadme" id="createReadme"/>
|
||||
<label class="radio">
|
||||
<input type="radio" name="initOption" value="EMPTY" checked/>
|
||||
<span class="strong">Create an empty repository</span>
|
||||
<div class="normal muted">
|
||||
Create an empty repository. You have to initialize by yourself initially.
|
||||
</div>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="initOption" value="README"/>
|
||||
<span class="strong">Initialize this repository with a README</span>
|
||||
<div class="normal muted">
|
||||
This will let you immediately clone the repository to your computer. Skip this step if you’re importing an existing repository.
|
||||
Create a repository which has README.md. You can clone the repository immediately.
|
||||
</div>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="initOption" value="COPY"/>
|
||||
<span class="strong">Copy existing git repository</span>
|
||||
<div class="normal muted">
|
||||
Create new repository from existing git repository.
|
||||
</div>
|
||||
</label>
|
||||
</fieldset>
|
||||
<input type="text" class="form-control" name="sourceUrl" id="sourceUrl" disabled placeholder="Source git repository URL..."/>
|
||||
<span id="error-sourceUrl" class="error"></span>
|
||||
<fieldset class="border-top form-actions">
|
||||
<input type="submit" class="btn btn-success" value="Create repository"/>
|
||||
</fieldset>
|
||||
@@ -83,4 +99,8 @@ $('#owner-dropdown a').click(function(){
|
||||
|
||||
$('#owner-dropdown span.strong').html($(this).find('span').html());
|
||||
});
|
||||
|
||||
$('input[name=initOption]').click(function () {
|
||||
$('#sourceUrl').prop('disabled', $('input[name=initOption]:checked').val() != 'COPY');
|
||||
});
|
||||
</script>
|
||||
|
||||
39
src/main/twirl/gitbucket/core/repo/creating.scala.html
Normal file
39
src/main/twirl/gitbucket/core/repo/creating.scala.html
Normal file
@@ -0,0 +1,39 @@
|
||||
@(owner: String, repository: String)(implicit context: gitbucket.core.controller.Context)
|
||||
@gitbucket.core.html.main("Creating...") {
|
||||
<div class="content-wrapper main-center">
|
||||
<div class="content body">
|
||||
<!-- Progress bar -->
|
||||
<div class="text-center" id="progress">
|
||||
<h2>Creating repository...</h2>
|
||||
<img src="@context.path/assets/common/images/indicator-bar.gif"/>
|
||||
</div>
|
||||
<!-- Error message -->
|
||||
<div id="error" style="display: none;">
|
||||
<h1>Failed to create repository</h1>
|
||||
<div id="errorMessage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<script>
|
||||
$(function () {
|
||||
checkCreating();
|
||||
});
|
||||
|
||||
function checkCreating() {
|
||||
$.get('@context.path/@owner/@repository/creating', function (data) {
|
||||
console.log(data);
|
||||
if (data.creating == true) {
|
||||
setTimeout(checkCreating, 2000);
|
||||
} else {
|
||||
if (data.error) {
|
||||
$('#errorMessage').text(data.error);
|
||||
$('#error').show();
|
||||
$('#progress').hide();
|
||||
} else {
|
||||
location.href = '@context.path/@owner/@repository';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user