mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-09 23:15:49 +01:00
Merge pull request #1883 from gitbucket/disable-merge-strategies
Add a option to enable/disable merge strategies
This commit is contained in:
6
src/main/resources/update/gitbucket-core_4.22.xml
Normal file
6
src/main/resources/update/gitbucket-core_4.22.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<changeSet>
|
||||||
|
<addColumn tableName="REPOSITORY">
|
||||||
|
<column name="MERGE_OPTIONS" type="varchar(200)" nullable="false" defaultValue="merge-commit,squash,rebase"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
@@ -53,5 +53,8 @@ object GitBucketCoreModule extends Module("gitbucket-core",
|
|||||||
new LiquibaseMigration("update/gitbucket-core_4.21.xml")
|
new LiquibaseMigration("update/gitbucket-core_4.21.xml")
|
||||||
),
|
),
|
||||||
new Version("4.21.1"),
|
new Version("4.21.1"),
|
||||||
new Version("4.21.2")
|
new Version("4.21.2"),
|
||||||
|
new Version("4.22.0",
|
||||||
|
new LiquibaseMigration("update/gitbucket-core_4.22.xml")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.scalatra.forms._
|
|||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.PersonIdent
|
import org.eclipse.jgit.lib.PersonIdent
|
||||||
import org.eclipse.jgit.revwalk.RevWalk
|
import org.eclipse.jgit.revwalk.RevWalk
|
||||||
|
import org.scalatra.BadRequest
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.collection.JavaConverters._
|
||||||
|
|
||||||
@@ -248,6 +249,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
params("id").toIntOpt.flatMap { issueId =>
|
params("id").toIntOpt.flatMap { issueId =>
|
||||||
val owner = repository.owner
|
val owner = repository.owner
|
||||||
val name = repository.name
|
val name = repository.name
|
||||||
|
if(repository.repository.options.mergeOptions.split(",").contains(form.strategy)){
|
||||||
LockUtil.lock(s"${owner}/${name}"){
|
LockUtil.lock(s"${owner}/${name}"){
|
||||||
getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
|
getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
|
||||||
using(Git.open(getRepositoryDir(owner, name))) { git =>
|
using(Git.open(getRepositoryDir(owner, name))) { git =>
|
||||||
@@ -309,6 +311,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else Some(BadRequest())
|
||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
externalIssuesUrl: Option[String],
|
externalIssuesUrl: Option[String],
|
||||||
wikiOption: String,
|
wikiOption: String,
|
||||||
externalWikiUrl: Option[String],
|
externalWikiUrl: Option[String],
|
||||||
allowFork: Boolean
|
allowFork: Boolean,
|
||||||
|
mergeOptions: Seq[String]
|
||||||
)
|
)
|
||||||
|
|
||||||
val optionsForm = mapping(
|
val optionsForm = mapping(
|
||||||
@@ -50,9 +51,17 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
"externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
|
"externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
|
||||||
"wikiOption" -> trim(label("Wiki Option" , text(required, featureOption))),
|
"wikiOption" -> trim(label("Wiki Option" , text(required, featureOption))),
|
||||||
"externalWikiUrl" -> trim(label("External Wiki URL" , optional(text(maxlength(200))))),
|
"externalWikiUrl" -> trim(label("External Wiki URL" , optional(text(maxlength(200))))),
|
||||||
"allowFork" -> trim(label("Allow Forking" , boolean()))
|
"allowFork" -> trim(label("Allow Forking" , boolean())),
|
||||||
|
"mergeOptions" -> new ValueType[Seq[String]]{
|
||||||
|
override def convert(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[String] =
|
||||||
|
params.get("mergeOptions").getOrElse(Nil)
|
||||||
|
override def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] =
|
||||||
|
if(params.get("mergeOptions").getOrElse(Nil).isEmpty) Seq("mergeOptions" -> "At least one option must be enabled.") else Nil
|
||||||
|
},
|
||||||
)(OptionsForm.apply)
|
)(OptionsForm.apply)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// for default branch
|
// for default branch
|
||||||
case class DefaultBranchForm(defaultBranch: String)
|
case class DefaultBranchForm(defaultBranch: String)
|
||||||
|
|
||||||
@@ -118,7 +127,8 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
form.externalIssuesUrl,
|
form.externalIssuesUrl,
|
||||||
form.wikiOption,
|
form.wikiOption,
|
||||||
form.externalWikiUrl,
|
form.externalWikiUrl,
|
||||||
form.allowFork
|
form.allowFork,
|
||||||
|
form.mergeOptions
|
||||||
)
|
)
|
||||||
// Change repository name
|
// Change repository name
|
||||||
if(repository.name != form.repositoryName){
|
if(repository.name != form.repositoryName){
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ trait RepositoryComponent extends TemplateComponent { self: Profile =>
|
|||||||
val wikiOption = column[String]("WIKI_OPTION")
|
val wikiOption = column[String]("WIKI_OPTION")
|
||||||
val externalWikiUrl = column[String]("EXTERNAL_WIKI_URL")
|
val externalWikiUrl = column[String]("EXTERNAL_WIKI_URL")
|
||||||
val allowFork = column[Boolean]("ALLOW_FORK")
|
val allowFork = column[Boolean]("ALLOW_FORK")
|
||||||
|
val mergeOptions = column[String]("MERGE_OPTIONS")
|
||||||
|
|
||||||
def * = (
|
def * = (
|
||||||
(userName, repositoryName, isPrivate, description.?, defaultBranch,
|
(userName, repositoryName, isPrivate, description.?, defaultBranch,
|
||||||
registeredDate, updatedDate, lastActivityDate, originUserName.?, originRepositoryName.?, parentUserName.?, parentRepositoryName.?),
|
registeredDate, updatedDate, lastActivityDate, originUserName.?, originRepositoryName.?, parentUserName.?, parentRepositoryName.?),
|
||||||
(issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork)
|
(issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork, mergeOptions)
|
||||||
).shaped <> (
|
).shaped <> (
|
||||||
{ case (repository, options) =>
|
{ case (repository, options) =>
|
||||||
Repository(
|
Repository(
|
||||||
@@ -88,5 +89,6 @@ case class RepositoryOptions(
|
|||||||
externalIssuesUrl: Option[String],
|
externalIssuesUrl: Option[String],
|
||||||
wikiOption: String,
|
wikiOption: String,
|
||||||
externalWikiUrl: Option[String],
|
externalWikiUrl: Option[String],
|
||||||
allowFork: Boolean
|
allowFork: Boolean,
|
||||||
|
mergeOptions: String
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ trait RepositoryService { self: AccountService =>
|
|||||||
externalIssuesUrl = None,
|
externalIssuesUrl = None,
|
||||||
wikiOption = "PUBLIC", // TODO DISABLE for the forked repository?
|
wikiOption = "PUBLIC", // TODO DISABLE for the forked repository?
|
||||||
externalWikiUrl = None,
|
externalWikiUrl = None,
|
||||||
allowFork = true
|
allowFork = true,
|
||||||
|
mergeOptions = "merge-commit,squash,rebase"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -362,14 +363,34 @@ trait RepositoryService { self: AccountService =>
|
|||||||
/**
|
/**
|
||||||
* Save repository options.
|
* Save repository options.
|
||||||
*/
|
*/
|
||||||
def saveRepositoryOptions(userName: String, repositoryName: String,
|
def saveRepositoryOptions(userName: String, repositoryName: String, description: Option[String], isPrivate: Boolean,
|
||||||
description: Option[String], isPrivate: Boolean,
|
issuesOption: String, externalIssuesUrl: Option[String], wikiOption: String, externalWikiUrl: Option[String],
|
||||||
issuesOption: String, externalIssuesUrl: Option[String],
|
allowFork: Boolean, mergeOptions: Seq[String])(implicit s: Session): Unit = {
|
||||||
wikiOption: String, externalWikiUrl: Option[String],
|
|
||||||
allowFork: Boolean)(implicit s: Session): Unit =
|
|
||||||
Repositories.filter(_.byRepository(userName, repositoryName))
|
Repositories.filter(_.byRepository(userName, repositoryName))
|
||||||
.map { r => (r.description.?, r.isPrivate, r.issuesOption, r.externalIssuesUrl.?, r.wikiOption, r.externalWikiUrl.?, r.allowFork, r.updatedDate) }
|
.map { r => (
|
||||||
.update (description, isPrivate, issuesOption, externalIssuesUrl, wikiOption, externalWikiUrl, allowFork, currentDate)
|
r.description.?,
|
||||||
|
r.isPrivate,
|
||||||
|
r.issuesOption,
|
||||||
|
r.externalIssuesUrl.?,
|
||||||
|
r.wikiOption,
|
||||||
|
r.externalWikiUrl.?,
|
||||||
|
r.allowFork,
|
||||||
|
r.mergeOptions,
|
||||||
|
r.updatedDate
|
||||||
|
) }
|
||||||
|
.update (
|
||||||
|
description,
|
||||||
|
isPrivate,
|
||||||
|
issuesOption,
|
||||||
|
externalIssuesUrl,
|
||||||
|
wikiOption,
|
||||||
|
externalWikiUrl,
|
||||||
|
allowFork,
|
||||||
|
mergeOptions.mkString(","),
|
||||||
|
currentDate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
def saveRepositoryDefaultBranch(userName: String, repositoryName: String,
|
def saveRepositoryDefaultBranch(userName: String, repositoryName: String,
|
||||||
defaultBranch: String)(implicit s: Session): Unit =
|
defaultBranch: String)(implicit s: Session): Unit =
|
||||||
|
|||||||
@@ -143,34 +143,48 @@
|
|||||||
<span id="error-message" class="error"></span>
|
<span id="error-message" class="error"></span>
|
||||||
<textarea name="message" style="height: 80px; margin-top: 8px; margin-bottom: 8px;" class="form-control">@issue.title</textarea>
|
<textarea name="message" style="height: 80px; margin-top: 8px; margin-bottom: 8px;" class="form-control">@issue.title</textarea>
|
||||||
<div>
|
<div>
|
||||||
|
@defining(originRepository.repository.options.mergeOptions.split(",")){ mergeOptions =>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button id="merge-strategy-btn" class="dropdown-toggle btn btn-default" data-toggle="dropdown">
|
<button id="merge-strategy-btn" class="dropdown-toggle btn btn-default" data-toggle="dropdown">
|
||||||
<span class="strong">Merge commit</span>
|
<span class="strong">
|
||||||
|
@(if(mergeOptions.contains("merge-commit")) "Merge commit"
|
||||||
|
else if(mergeOptions.contains("squash")) "Squash"
|
||||||
|
else if(mergeOptions.contains("rebase")) "Rebase")
|
||||||
|
</span>
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
@if(mergeOptions.contains("merge-commit")){
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:void(0);" class="merge-strategy" data-value="merge-commit">
|
<a href="javascript:void(0);" class="merge-strategy" data-value="merge-commit">
|
||||||
<strong>Merge commit</strong><br>These commits will be added to the base branch via a merge commit.
|
<strong>Merge commit</strong><br>These commits will be added to the base branch via a merge commit.
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
|
@if(mergeOptions.contains("squash")){
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:void(0);" class="merge-strategy" data-value="squash">
|
<a href="javascript:void(0);" class="merge-strategy" data-value="squash">
|
||||||
<strong>Squash</strong><br>These commits will be combined into one commit in the base branch.
|
<strong>Squash</strong><br>These commits will be combined into one commit in the base branch.
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
|
@if(mergeOptions.contains("rebase")){
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:void(0);" class="merge-strategy" data-value="rebase">
|
<a href="javascript:void(0);" class="merge-strategy" data-value="rebase">
|
||||||
<strong>Rebase</strong><br>These commits will be rebased and added to the base branch.
|
<strong>Rebase</strong><br>These commits will be rebased and added to the base branch.
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<input type="button" class="btn btn-default" value="Cancel" id="cancel-merge-pull-request"/>
|
<input type="button" class="btn btn-default" value="Cancel" id="cancel-merge-pull-request"/>
|
||||||
<input type="submit" class="btn btn-success" value="Confirm merge"/>
|
<input type="submit" class="btn btn-success" value="Confirm merge"/>
|
||||||
<input type="hidden" name="strategy" value="merge-commit"/>
|
<input type="hidden" name="strategy" value="@(if(mergeOptions.contains("merge-commit")) "merge-commit"
|
||||||
|
else if(mergeOptions.contains("squash")) "squash"
|
||||||
|
else if(mergeOptions.contains("rebase")) "rebase")"/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -112,6 +112,38 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading strong">Merge strategy</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
Select pull request merge strategies which are available in this repository. At least one option must be enabled.
|
||||||
|
<fieldset class="form-group">
|
||||||
|
@defining(repository.repository.options.mergeOptions.split(",")){ mergeOptions =>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label for="mergeOptions_MergeCommit">
|
||||||
|
<input type="checkbox" name="mergeOptions" id="mergeOptions_MergeCommit" value="merge-commit" @if(mergeOptions.contains("merge-commit")){checked}>
|
||||||
|
<span class="strong">Merge commit</span>
|
||||||
|
<div class="normal muted">Commits will be added to the base branch via a merge commit.</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label for="mergeOptions_Squash">
|
||||||
|
<input type="checkbox" name="mergeOptions" id="mergeOptions_Squash" value="squash" @if(mergeOptions.contains("squash")){checked}>
|
||||||
|
<span class="strong">Squash</span>
|
||||||
|
<div class="normal muted">Commits will be combined into one commit in the base branch.</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label for="mergeOptions_Rebase">
|
||||||
|
<input type="checkbox" name="mergeOptions" id="mergeOptions_Rebase" value="rebase" @if(mergeOptions.contains("rebase")){checked}>
|
||||||
|
<span class="strong">Rebase</span>
|
||||||
|
<div class="normal muted">Commits will be rebased and added to the base branch.</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<span id="error-mergeOptions" class="error"></span>
|
||||||
|
}
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="align-right" style="margin-top: 20px;">
|
<div class="align-right" style="margin-top: 20px;">
|
||||||
<input type="submit" class="btn btn-success" value="Apply changes"/>
|
<input type="submit" class="btn btn-success" value="Apply changes"/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user