diff --git a/src/main/resources/update/gitbucket-core_4.22.xml b/src/main/resources/update/gitbucket-core_4.22.xml
new file mode 100644
index 0000000..98a3b3d
--- /dev/null
+++ b/src/main/resources/update/gitbucket-core_4.22.xml
@@ -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>
diff --git a/src/main/scala/gitbucket/core/GitBucketCoreModule.scala b/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
index 2f3df19..0fd6742 100644
--- a/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
+++ b/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
@@ -53,5 +53,8 @@
     new LiquibaseMigration("update/gitbucket-core_4.21.xml")
   ),
   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")
+  )
 )
diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
index 18fef96..395b4f9 100644
--- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
+++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
@@ -17,6 +17,7 @@
 import org.eclipse.jgit.api.Git
 import org.eclipse.jgit.lib.PersonIdent
 import org.eclipse.jgit.revwalk.RevWalk
+import org.scalatra.BadRequest
 
 import scala.collection.JavaConverters._
 
@@ -248,67 +249,69 @@
     params("id").toIntOpt.flatMap { issueId =>
       val owner = repository.owner
       val name  = repository.name
-      LockUtil.lock(s"${owner}/${name}"){
-        getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
-          using(Git.open(getRepositoryDir(owner, name))) { git =>
-            // mark issue as merged and close.
-            val loginAccount = context.loginAccount.get
-            val commentId = createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
-            createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
-            updateClosed(owner, name, issueId, true)
+      if(repository.repository.options.mergeOptions.split(",").contains(form.strategy)){
+        LockUtil.lock(s"${owner}/${name}"){
+          getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
+            using(Git.open(getRepositoryDir(owner, name))) { git =>
+              // mark issue as merged and close.
+              val loginAccount = context.loginAccount.get
+              val commentId = createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
+              createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
+              updateClosed(owner, name, issueId, true)
 
-            // record activity
-            recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
+              // record activity
+              recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
 
-            val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
-              pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
+              val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
+                pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
 
-            val revCommits = using(new RevWalk( git.getRepository )){ revWalk =>
-              commits.flatten.map { commit =>
-                revWalk.parseCommit(git.getRepository.resolve(commit.id))
+              val revCommits = using(new RevWalk( git.getRepository )){ revWalk =>
+                commits.flatten.map { commit =>
+                  revWalk.parseCommit(git.getRepository.resolve(commit.id))
+                }
+              }.reverse
+
+              // merge git repository
+              form.strategy match {
+                case "merge-commit" =>
+                  mergePullRequest(git, pullreq.branch, issueId,
+                    s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
+                    new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
+                case "rebase" =>
+                  rebasePullRequest(git, pullreq.branch, issueId, revCommits,
+                    new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
+                case "squash" =>
+                  squashPullRequest(git, pullreq.branch, issueId,
+                    s"${issue.title} (#${issueId})\n\n" + form.message,
+                    new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
               }
-            }.reverse
 
-            // merge git repository
-            form.strategy match {
-              case "merge-commit" =>
-                mergePullRequest(git, pullreq.branch, issueId,
-                  s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
-                  new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
-              case "rebase" =>
-                rebasePullRequest(git, pullreq.branch, issueId, revCommits,
-                  new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
-              case "squash" =>
-                squashPullRequest(git, pullreq.branch, issueId,
-                  s"${issue.title} (#${issueId})\n\n" + form.message,
-                  new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
-            }
-
-            // close issue by content of pull request
-            val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
-            if(pullreq.branch == defaultBranch){
-              commits.flatten.foreach { commit =>
-                closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
+              // close issue by content of pull request
+              val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
+              if(pullreq.branch == defaultBranch){
+                commits.flatten.foreach { commit =>
+                  closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
+                }
+                closeIssuesFromMessage(issue.title + " " + issue.content.getOrElse(""), loginAccount.userName, owner, name)
+                closeIssuesFromMessage(form.message, loginAccount.userName, owner, name)
               }
-              closeIssuesFromMessage(issue.title + " " + issue.content.getOrElse(""), loginAccount.userName, owner, name)
-              closeIssuesFromMessage(form.message, loginAccount.userName, owner, name)
+
+              updatePullRequests(owner, name, pullreq.branch)
+
+              // call web hook
+              callPullRequestWebHook("closed", repository, issueId, context.baseUrl, context.loginAccount.get)
+
+              // call hooks
+              PluginRegistry().getPullRequestHooks.foreach{ h =>
+                h.addedComment(commentId, form.message, issue, repository)
+                h.merged(issue, repository)
+              }
+
+              redirect(s"/${owner}/${name}/pull/${issueId}")
             }
-
-            updatePullRequests(owner, name, pullreq.branch)
-
-            // call web hook
-            callPullRequestWebHook("closed", repository, issueId, context.baseUrl, context.loginAccount.get)
-
-            // call hooks
-            PluginRegistry().getPullRequestHooks.foreach{ h =>
-              h.addedComment(commentId, form.message, issue, repository)
-              h.merged(issue, repository)
-            }
-
-            redirect(s"/${owner}/${name}/pull/${issueId}")
           }
         }
-      }
+      } else Some(BadRequest())
     } getOrElse NotFound()
   })
 
diff --git a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
index b1e5b3d..ffe98c1 100644
--- a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
+++ b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
@@ -39,20 +39,29 @@
     externalIssuesUrl: Option[String],
     wikiOption: String,
     externalWikiUrl: Option[String],
-    allowFork: Boolean
+    allowFork: Boolean,
+    mergeOptions: Seq[String]
   )
 
   val optionsForm = mapping(
-    "repositoryName"    -> trim(label("Repository Name"    , text(required, maxlength(100), repository, renameRepositoryName))),
-    "description"       -> trim(label("Description"        , optional(text()))),
-    "isPrivate"         -> trim(label("Repository Type"    , boolean())),
-    "issuesOption"      -> trim(label("Issues Option"      , text(required, featureOption))),
-    "externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
-    "wikiOption"        -> trim(label("Wiki Option"        , text(required, featureOption))),
-    "externalWikiUrl"   -> trim(label("External Wiki URL"  , optional(text(maxlength(200))))),
-    "allowFork"         -> trim(label("Allow Forking"      , boolean()))
+    "repositoryName"     -> trim(label("Repository Name"    , text(required, maxlength(100), repository, renameRepositoryName))),
+    "description"        -> trim(label("Description"        , optional(text()))),
+    "isPrivate"          -> trim(label("Repository Type"    , boolean())),
+    "issuesOption"       -> trim(label("Issues Option"      , text(required, featureOption))),
+    "externalIssuesUrl"  -> trim(label("External Issues URL", optional(text(maxlength(200))))),
+    "wikiOption"         -> trim(label("Wiki Option"        , text(required, featureOption))),
+    "externalWikiUrl"    -> trim(label("External Wiki URL"  , optional(text(maxlength(200))))),
+    "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)
 
+
+
   // for default branch
   case class DefaultBranchForm(defaultBranch: String)
 
@@ -118,7 +127,8 @@
       form.externalIssuesUrl,
       form.wikiOption,
       form.externalWikiUrl,
-      form.allowFork
+      form.allowFork,
+      form.mergeOptions
     )
     // Change repository name
     if(repository.name != form.repositoryName){
diff --git a/src/main/scala/gitbucket/core/model/Repository.scala b/src/main/scala/gitbucket/core/model/Repository.scala
index 66cb641..1e06a39 100644
--- a/src/main/scala/gitbucket/core/model/Repository.scala
+++ b/src/main/scala/gitbucket/core/model/Repository.scala
@@ -22,11 +22,12 @@
     val wikiOption           = column[String]("WIKI_OPTION")
     val externalWikiUrl      = column[String]("EXTERNAL_WIKI_URL")
     val allowFork            = column[Boolean]("ALLOW_FORK")
+    val mergeOptions         = column[String]("MERGE_OPTIONS")
 
     def * = (
       (userName, repositoryName, isPrivate, description.?, defaultBranch,
       registeredDate, updatedDate, lastActivityDate, originUserName.?, originRepositoryName.?, parentUserName.?, parentRepositoryName.?),
-      (issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork)
+      (issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork, mergeOptions)
     ).shaped <> (
       { case (repository, options) =>
         Repository(
@@ -88,5 +89,6 @@
   externalIssuesUrl: Option[String],
   wikiOption: String,
   externalWikiUrl: Option[String],
-  allowFork: Boolean
+  allowFork: Boolean,
+  mergeOptions: String
 )
diff --git a/src/main/scala/gitbucket/core/service/RepositoryService.scala b/src/main/scala/gitbucket/core/service/RepositoryService.scala
index 5997629..34bb954 100644
--- a/src/main/scala/gitbucket/core/service/RepositoryService.scala
+++ b/src/main/scala/gitbucket/core/service/RepositoryService.scala
@@ -46,7 +46,8 @@
           externalIssuesUrl    = None,
           wikiOption           = "PUBLIC", // TODO DISABLE for the forked repository?
           externalWikiUrl      = None,
-          allowFork            = true
+          allowFork            = true,
+          mergeOptions         = "merge-commit,squash,rebase"
         )
       )
 
@@ -362,14 +363,34 @@
   /**
    * Save repository options.
    */
-  def saveRepositoryOptions(userName: String, repositoryName: String,
-      description: Option[String], isPrivate: Boolean,
-      issuesOption: String, externalIssuesUrl: Option[String],
-      wikiOption: String, externalWikiUrl: Option[String],
-      allowFork: Boolean)(implicit s: Session): Unit =
+  def saveRepositoryOptions(userName: String, repositoryName: String, description: Option[String], isPrivate: Boolean,
+      issuesOption: String, externalIssuesUrl: Option[String], wikiOption: String, externalWikiUrl: Option[String],
+      allowFork: Boolean, mergeOptions: Seq[String])(implicit s: Session): Unit = {
+
     Repositories.filter(_.byRepository(userName, repositoryName))
-      .map { r => (r.description.?, r.isPrivate, r.issuesOption, r.externalIssuesUrl.?, r.wikiOption, r.externalWikiUrl.?, r.allowFork, r.updatedDate) }
-      .update (description, isPrivate, issuesOption, externalIssuesUrl, wikiOption, externalWikiUrl, allowFork, currentDate)
+      .map { r => (
+        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,
       defaultBranch: String)(implicit s: Session): Unit =
diff --git a/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html b/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html
index 3332c1f..e80e60c 100644
--- a/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html
+++ b/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html
@@ -143,34 +143,48 @@
         <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>
         <div>
+        @defining(originRepository.repository.options.mergeOptions.split(",")){ mergeOptions =>
           <div class="btn-group">
             <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>
             </button>
             <ul class="dropdown-menu">
-              <li>
-                <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.
-                </a>
-              </li>
-              <li>
-                <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.
-                </a>
-              </li>
-              <li>
-                <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.
-                </a>
-              </li>
+              @if(mergeOptions.contains("merge-commit")){
+                <li>
+                  <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.
+                  </a>
+                </li>
+              }
+              @if(mergeOptions.contains("squash")){
+                <li>
+                  <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.
+                  </a>
+                </li>
+              }
+              @if(mergeOptions.contains("rebase")){
+                <li>
+                  <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.
+                  </a>
+                </li>
+              }
             </ul>
           </div>
           <div class="pull-right">
             <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="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>
       </form>
     </div>
diff --git a/src/main/twirl/gitbucket/core/settings/options.scala.html b/src/main/twirl/gitbucket/core/settings/options.scala.html
index 7589425..4e39f8e 100644
--- a/src/main/twirl/gitbucket/core/settings/options.scala.html
+++ b/src/main/twirl/gitbucket/core/settings/options.scala.html
@@ -112,6 +112,38 @@
             </fieldset>
           </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;">
           <input type="submit" class="btn btn-success" value="Apply changes"/>
         </div>