diff --git a/src/main/scala/gitbucket/core/controller/AccountController.scala b/src/main/scala/gitbucket/core/controller/AccountController.scala index 239bdf6..7c2a8f4 100644 --- a/src/main/scala/gitbucket/core/controller/AccountController.scala +++ b/src/main/scala/gitbucket/core/controller/AccountController.scala @@ -12,13 +12,10 @@ 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._ -import scala.concurrent.ExecutionContext.Implicits.global - class AccountController extends AccountControllerBase with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator @@ -530,12 +527,7 @@ post("/new", newRepositoryForm)(usersOnly { form => LockUtil.lock(s"${form.owner}/${form.name}"){ if(getRepository(form.owner, form.name).isEmpty){ - // Create the repository - val f = createRepository(context.loginAccount.get, form.owner, form.name, form.description, form.isPrivate, form.initOption, form.sourceUrl).map { _ => - // Call hooks - PluginRegistry().getRepositoryHooks.foreach(_.created(form.owner, form.name)) - } - //Await.result(f, Duration.Inf) + createRepository(context.loginAccount.get, form.owner, form.name, form.description, form.isPrivate, form.initOption, form.sourceUrl) } } @@ -569,66 +561,15 @@ 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() }) diff --git a/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala b/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala index cdb3e59..65e95a9 100644 --- a/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala +++ b/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala @@ -6,8 +6,10 @@ 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 @@ -126,15 +128,78 @@ // Record activity recordCreateRepositoryActivity(owner, name, loginUserName) + + // Call hooks + PluginRegistry().getRepositoryHooks.foreach(_.created(owner, name)) } RepositoryCreationService.endCreation(owner, name, None) } catch { - case ex: Exception => { - ex.printStackTrace() - RepositoryCreationService.endCreation(owner, name, Some(ex.toString)) + case ex: Exception => RepositoryCreationService.endCreation(owner, name, Some(ex.toString)) + } + } + + 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) + + 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)) } }