diff --git a/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala b/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala index f542230..71d8144 100644 --- a/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala +++ b/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala @@ -106,6 +106,7 @@ if (isUpdating) { if (hasDeveloperRole(repository.owner, repository.name, Some(account))) { request.setAttribute(Keys.Request.UserName, account.userName) + request.setAttribute(Keys.Request.RepositoryLockKey, s"${repository.owner}/${repository.name}") true } else false } else if (repository.repository.isPrivate) { diff --git a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala index de87ee2..2c9e43f 100644 --- a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala +++ b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala @@ -55,11 +55,24 @@ res.sendRedirect(baseUrl(req) + "/" + paths.dropRight(1).last + "/" + paths.last) } else if (req.getMethod.toUpperCase == "POST" && req.getRequestURI.endsWith("/info/lfs/objects/batch")) { - serviceGitLfsBatchAPI(req, res) - + withLockRepository(req) { + serviceGitLfsBatchAPI(req, res) + } } else { // response for git client - super.service(req, res) + withLockRepository(req) { + super.service(req, res) + } + } + } + + private def withLockRepository[T](req: HttpServletRequest)(f: => T): T = { + if (req.hasAttribute(Keys.Request.RepositoryLockKey)) { + LockUtil.lock(req.getAttribute(Keys.Request.RepositoryLockKey).asInstanceOf[String]) { + f + } + } else { + f } } diff --git a/src/main/scala/gitbucket/core/util/Keys.scala b/src/main/scala/gitbucket/core/util/Keys.scala index cf3135c..cf24913 100644 --- a/src/main/scala/gitbucket/core/util/Keys.scala +++ b/src/main/scala/gitbucket/core/util/Keys.scala @@ -87,6 +87,11 @@ val UserName = "USER_NAME" /** + * Request key for the Lock key which is used during Git repository write access. + */ + val RepositoryLockKey = "REPOSITORY_LOCK_KEY" + + /** * Generate request key for the request cache. */ def Cache(key: String) = s"cache.${key}"