From cdb0531a42b8cd76a70584c0f0c2dd255adc3800 Mon Sep 17 00:00:00 2001
From: Slavek Kabrda <bkabrda@redhat.com>
Date: Sep 21 2018 09:02:48 +0000
Subject: [PATCH 1/2] Make it possible to disable non-FF merges for a project


---

diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py
index a476fde..67f3bc8 100644
--- a/pagure/internal/__init__.py
+++ b/pagure/internal/__init__.py
@@ -215,39 +215,26 @@ def mergeable_request_pull():
         response.status_code = 404
         return response
 
-    if request.merge_status and not force:
-        return flask.jsonify(
-            {
-                "code": request.merge_status,
-                "short_code": MERGE_OPTIONS[request.merge_status][
-                    "short_code"
-                ],
-                "message": MERGE_OPTIONS[request.merge_status]["message"],
-            }
-        )
-
-    try:
-        merge_status = pagure.lib.git.merge_pull_request(
-            session=flask.g.session,
-            request=request,
-            username=None,
-            domerge=False,
-        )
-    except pygit2.GitError as err:
-        response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
-        response.status_code = 409
-        return response
-    except pagure.exceptions.PagureException as err:
-        response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
-        response.status_code = 500
-        return response
+    merge_status = request.merge_status
+    if not merge_status or force:
+        try:
+            merge_status = pagure.lib.git.merge_pull_request(
+                session=flask.g.session,
+                request=request,
+                username=None,
+                domerge=False,
+            )
+        except pygit2.GitError as err:
+            response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
+            response.status_code = 409
+            return response
+        except pagure.exceptions.PagureException as err:
+            response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
+            response.status_code = 500
+            return response
 
     return flask.jsonify(
-        {
-            "code": merge_status,
-            "short_code": MERGE_OPTIONS[merge_status]["short_code"],
-            "message": MERGE_OPTIONS[merge_status]["message"],
-        }
+        pagure.utils.get_merge_options(request, merge_status)
     )
 
 
diff --git a/pagure/lib/git.py b/pagure/lib/git.py
index aa9121c..e9ac914 100644
--- a/pagure/lib/git.py
+++ b/pagure/lib/git.py
@@ -1631,6 +1631,11 @@ def merge_pull_request(session, request, username, domerge=True):
                     return "CONFLICTS"
 
             if domerge:
+                if request.project.settings.get(
+                    "disable_non_fast-forward_merges", False
+                ):
+                    _log.info("  Merge non-FF PR is disabled for this project")
+                    return "MERGE"
                 _log.info("  Writing down merge commit")
                 head = new_repo.lookup_reference("HEAD").get_object()
                 _log.info(
diff --git a/pagure/lib/model.py b/pagure/lib/model.py
index 853f723..7ade5a5 100644
--- a/pagure/lib/model.py
+++ b/pagure/lib/model.py
@@ -629,6 +629,7 @@ class Project(BASE):
             "notify_on_pull-request_flag": False,
             "notify_on_commit_flag": False,
             "issue_tracker_read_only": False,
+            "disable_non_fast-forward_merges": False,
         }
 
         if self._settings:
diff --git a/pagure/utils.py b/pagure/utils.py
index 43433c8..7f08e65 100644
--- a/pagure/utils.py
+++ b/pagure/utils.py
@@ -498,3 +498,41 @@ def is_true(value, trueish=("1", "true", "t", "y")):
     else:
         value = str(value)
     return value.strip().lower() in trueish
+
+
+def get_merge_options(request, merge_status):
+    MERGE_OPTIONS = {
+        "NO_CHANGE": {
+            "code": "NO_CHANGE",
+            "short_code": "No changes",
+            "message": "Nothing to change, git is up to date",
+        },
+        "FFORWARD": {
+            "code": "FFORWARD",
+            "short_code": "Ok",
+            "message": "The pull-request can be merged and fast-forwarded",
+        },
+        "CONFLICTS": {
+            "code": "CONFLICTS",
+            "short_code": "Conflicts",
+            "message": "The pull-request cannot be merged due to conflicts",
+        },
+        "MERGE-non-ff-ok": {
+            "code": "MERGE",
+            "short_code": "With merge",
+            "message": "The pull-request can be merged with a merge commit",
+        },
+        "MERGE-non-ff-bad": {
+            "code": "CONFLICTS",
+            "short_code": "Conflicts",
+            "message": "The pull-request must be rebased before merging",
+        }
+    }
+
+    if merge_status == "MERGE":
+        if request.project.settings.get("disable_non_fast-forward_merges", False):
+            merge_status += "-non-ff-bad"
+        else:
+            merge_status += "-non-ff-ok"
+
+    return MERGE_OPTIONS[merge_status]

From 98d023a2cf1f502f6b6528e917cb1a879196dbad Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Sep 21 2018 09:28:55 +0000
Subject: [PATCH 2/2] Fix the tests for the addition of disable_non_fast-forward_merges


Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>

---

diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py
index 67f3bc8..c9203c2 100644
--- a/pagure/internal/__init__.py
+++ b/pagure/internal/__init__.py
@@ -225,11 +225,13 @@ def mergeable_request_pull():
                 domerge=False,
             )
         except pygit2.GitError as err:
-            response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
+            response = flask.jsonify(
+                {"code": "CONFLICTS", "message": "%s" % err})
             response.status_code = 409
             return response
         except pagure.exceptions.PagureException as err:
-            response = flask.jsonify({"code": "CONFLICTS", "message": "%s" % err})
+            response = flask.jsonify(
+                {"code": "CONFLICTS", "message": "%s" % err})
             response.status_code = 500
             return response
 
diff --git a/pagure/utils.py b/pagure/utils.py
index 7f08e65..74e84e5 100644
--- a/pagure/utils.py
+++ b/pagure/utils.py
@@ -530,7 +530,8 @@ def get_merge_options(request, merge_status):
     }
 
     if merge_status == "MERGE":
-        if request.project.settings.get("disable_non_fast-forward_merges", False):
+        if request.project.settings.get(
+                "disable_non_fast-forward_merges", False):
             merge_status += "-non-ff-bad"
         else:
             merge_status += "-non-ff-ok"
diff --git a/tests/test_pagure_lib_git.py b/tests/test_pagure_lib_git.py
index 84d44a9..693dbef 100644
--- a/tests/test_pagure_lib_git.py
+++ b/tests/test_pagure_lib_git.py
@@ -1697,7 +1697,7 @@ new file mode 100644
 index 0000000..60f7480
 --- /dev/null
 +++ b/456
-@@ -0,0 +1,139 @@
+@@ -0,0 +1,141 @@
 +{
 +    "assignee": null,
 +    "branch": "master",
@@ -1744,6 +1744,7 @@ index 0000000..60f7480
 +            "Only_assignee_can_merge_pull-request": false,
 +            "Web-hooks": null,
 +            "always_merge": false,
++            "disable_non_fast-forward_merges": false,
 +            "fedmsg_notifications": true,
 +            "issue_tracker": true,
 +            "issue_tracker_read_only": false,
@@ -1800,6 +1801,7 @@ index 0000000..60f7480
 +            "Only_assignee_can_merge_pull-request": false,
 +            "Web-hooks": null,
 +            "always_merge": false,
++            "disable_non_fast-forward_merges": false,
 +            "fedmsg_notifications": true,
 +            "issue_tracker": true,
 +            "issue_tracker_read_only": false,

