changeset 7672:99edd97366e3

locking: drop the pull-to-lock / push-to-unlock functionality The feature is not worth the maintenance cost. The locking is too coarse and unflexible with insufficient UI and UX. The implementation is also quite invasive in tricky areas of the code, and thus high maintenance. Dropping this will enable other cleanup ... or at least make it easier.
author Mads Kiilerich <mads@kiilerich.com>
date Wed, 16 Jan 2019 02:32:35 +0100
parents b8f77a47d485
children 642847355a10
files development.ini docs/api/api.rst docs/index.rst docs/usage/locking.rst kallithea/alembic/versions/ad357ccd9521_drop_locking.py kallithea/config/routing.py kallithea/controllers/admin/repos.py kallithea/controllers/api/api.py kallithea/controllers/files.py kallithea/lib/base.py kallithea/lib/celerylib/tasks.py kallithea/lib/db_manage.py kallithea/lib/exceptions.py kallithea/lib/hooks.py kallithea/lib/middleware/simplegit.py kallithea/lib/middleware/simplehg.py kallithea/lib/paster_commands/template.ini.mako kallithea/lib/utils.py kallithea/lib/utils2.py kallithea/model/db.py kallithea/model/forms.py kallithea/model/repo.py kallithea/model/repo_group.py kallithea/model/scm.py kallithea/model/validators.py kallithea/templates/admin/defaults/defaults.html kallithea/templates/admin/repo_groups/repo_group_edit_settings.html kallithea/templates/admin/repos/repo_edit_advanced.html kallithea/templates/admin/repos/repo_edit_settings.html kallithea/templates/base/base.html kallithea/templates/summary/summary.html kallithea/tests/api/api_base.py kallithea/tests/fixture.py kallithea/tests/functional/test_admin_defaults.py kallithea/tests/other/test_vcs_operations.py
diffstat 35 files changed, 71 insertions(+), 1001 deletions(-) [+]
line wrap: on
line diff
--- a/development.ini	Wed May 22 18:06:55 2019 -0400
+++ b/development.ini	Wed Jan 16 02:32:35 2019 +0100
@@ -219,10 +219,6 @@
 ## handling that. Set this variable to 403 to return HTTPForbidden
 auth_ret_code =
 
-## locking return code. When repository is locked return this HTTP code. 2XX
-## codes don't break the transactions while 4XX codes do
-lock_ret_code = 423
-
 ## allows to change the repository location in settings page
 allow_repo_location_change = True
 
--- a/docs/api/api.rst	Wed May 22 18:06:55 2019 -0400
+++ b/docs/api/api.rst	Wed Jan 16 02:32:35 2019 +0100
@@ -162,37 +162,6 @@
     result : "Caches of repository `<reponame>`"
     error :  null
 
-lock
-^^^^
-
-Set the locking state on the given repository by the given user.
-If the param ``userid`` is skipped, it is set to the ID of the user who is calling this method.
-If param ``locked`` is skipped, the current lock state of the repository is returned.
-This command can only be executed using the api_key of a user with admin rights, or that of a regular user with admin or write access to the repository.
-
-INPUT::
-
-    id : <id_for_response>
-    api_key : "<api_key>"
-    method :  "lock"
-    args :    {
-                "repoid" : "<reponame or repo_id>"
-                "userid" : "<user_id or username = Optional(=apiuser)>",
-                "locked" : "<bool true|false = Optional(=None)>"
-              }
-
-OUTPUT::
-
-    id : <id_given_in_input>
-    result : {
-                 "repo": "<reponame>",
-                 "locked": "<bool true|false>",
-                 "locked_since": "<float lock_time>",
-                 "locked_by": "<username>",
-                 "msg": "User `<username>` set lock state for repo `<reponame>` to `<false|true>`"
-             }
-    error :  null
-
 get_ip
 ^^^^^^
 
@@ -601,7 +570,6 @@
                 "repo_type" :        "<repo_type>",
                 "clone_uri" :        "<clone_uri>",
                 "enable_downloads":  "<bool>",
-                "enable_locking":    "<bool>",
                 "enable_statistics": "<bool>",
                 "private":           "<bool>",
                 "created_on" :       "<date_time_created>",
@@ -755,7 +723,6 @@
                 "owner":             "<repo_owner>",
                 "fork_of":           "<name_of_fork_parent>",
                 "enable_downloads":  "<bool>",
-                "enable_locking":    "<bool>",
                 "enable_statistics": "<bool>",
               },

@@ -820,7 +787,6 @@
                 "clone_uri" :        "<clone_uri> = Optional(None)",
                 "landing_rev" :      "<landing_rev> = Optional('tip')",
                 "enable_downloads":  "<bool> = Optional(False)",
-                "enable_locking":    "<bool> = Optional(False)",
                 "enable_statistics": "<bool> = Optional(False)",
               }
 
@@ -841,7 +807,6 @@
                 "owner":             "<username or user_id>",
                 "fork_of":           "<name_of_fork_parent>",
                 "enable_downloads":  "<bool>",
-                "enable_locking":    "<bool>",
                 "enable_statistics": "<bool>",
               },
             }
@@ -870,7 +835,6 @@
                 "clone_uri" :        "<clone_uri> = Optional(None)",
                 "landing_rev" :      "<landing_rev> = Optional('tip')",
                 "enable_downloads":  "<bool> = Optional(False)",
-                "enable_locking":    "<bool> = Optional(False)",
                 "enable_statistics": "<bool> = Optional(False)",
               }
 
@@ -891,7 +855,6 @@
                 "owner":             "<username or user_id>",
                 "fork_of":           "<name_of_fork_parent>",
                 "enable_downloads":  "<bool>",
-                "enable_locking":    "<bool>",
                 "enable_statistics": "<bool>",
                 "last_changeset":    {
                                        "author":   "<full_author>",
@@ -901,8 +864,6 @@
                                        "revision": "<numeric_revision>",
                                        "short_id": "<short_id>"
                                      }
-                "locked_by": "<username>",
-                "locked_date": "<float lock_time>",
               },
             }
     error:  null
--- a/docs/index.rst	Wed May 22 18:06:55 2019 -0400
+++ b/docs/index.rst	Wed Jan 16 02:32:35 2019 +0100
@@ -63,7 +63,6 @@
 
    usage/general
    usage/vcs_notes
-   usage/locking
    usage/statistics
    api/api
 
--- a/docs/usage/locking.rst	Wed May 22 18:06:55 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-.. _locking:
-
-==================
-Repository locking
-==================
-
-Kallithea has a *repository locking* feature, disabled by default. When
-enabled, every initial clone and every pull gives users (with write permission)
-the exclusive right to do a push.
-
-When repository locking is enabled, repositories get a ``locked`` flag.
-The hg/git commands ``hg/git clone``, ``hg/git pull``,
-and ``hg/git push`` influence this state:
-
-- A ``clone`` or ``pull`` action locks the target repository
-  if the user has write/admin permissions on this repository.
-
-- Kallithea will remember the user who locked the repository so only this
-  specific user can unlock the repo by performing a ``push``
-  command.
-
-- Every other command on a locked repository from this user and every command
-  from any other user will result in an HTTP return code 423 (Locked).
-  Additionally, the HTTP error will mention the user that locked the repository
-  (e.g., “repository <repo> locked by user <user>”).
-
-Each repository can be manually unlocked by an administrator from the
-repository settings menu.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/alembic/versions/ad357ccd9521_drop_locking.py	Wed Jan 16 02:32:35 2019 +0100
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Drop locking
+
+Revision ID: ad357ccd9521
+Revises: a020f7044fd6
+Create Date: 2019-01-08
+
+"""
+
+# The following opaque hexadecimal identifiers ("revisions") are used
+# by Alembic to track this migration script and its relations to others.
+revision = 'ad357ccd9521'
+down_revision = 'a020f7044fd6'
+branch_labels = None
+depends_on = None
+
+from alembic import op
+import sqlalchemy as sa
+from kallithea.model.db import Ui
+from sqlalchemy import Table, MetaData
+
+meta = MetaData()
+
+
+def upgrade():
+    with op.batch_alter_table('groups', schema=None) as batch_op:
+        batch_op.drop_column('enable_locking')
+
+    with op.batch_alter_table('repositories', schema=None) as batch_op:
+        batch_op.drop_column('locked')
+        batch_op.drop_column('enable_locking')
+
+    meta.bind = op.get_bind()
+    ui = Table(Ui.__tablename__, meta, autoload=True)
+    ui.delete().where(ui.c.ui_key == 'prechangegroup.push_lock_handling').execute()
+    ui.delete().where(ui.c.ui_key == 'preoutgoing.pull_lock_handling').execute()
+
+
+def downgrade():
+    with op.batch_alter_table('repositories', schema=None) as batch_op:
+        batch_op.add_column(sa.Column('enable_locking', sa.BOOLEAN(), nullable=False, default=False))
+        batch_op.add_column(sa.Column('locked', sa.VARCHAR(length=255), nullable=True, default=False))
+
+    with op.batch_alter_table('groups', schema=None) as batch_op:
+        batch_op.add_column(sa.Column('enable_locking', sa.BOOLEAN(), nullable=False, default=False))
+
+    # Note: not restoring hooks
--- a/kallithea/config/routing.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/config/routing.py	Wed Jan 16 02:32:35 2019 +0100
@@ -533,13 +533,6 @@
                  controller='admin/repos', action="edit_advanced",
                  conditions=dict(method=["GET"], function=check_repo))
 
-    rmap.connect("edit_repo_advanced_locking", "/{repo_name:.*?}/settings/advanced/locking",
-                 controller='admin/repos', action="edit_advanced_locking",
-                 conditions=dict(method=["POST"], function=check_repo))
-    rmap.connect('toggle_locking', "/{repo_name:.*?}/settings/advanced/locking_toggle",
-                 controller='admin/repos', action="toggle_locking",
-                 conditions=dict(method=["GET"], function=check_repo))
-
     rmap.connect("edit_repo_advanced_journal", "/{repo_name:.*?}/settings/advanced/journal",
                  controller='admin/repos', action="edit_advanced_journal",
                  conditions=dict(method=["POST"], function=check_repo))
--- a/kallithea/controllers/admin/repos.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/controllers/admin/repos.py	Wed Jan 16 02:32:35 2019 +0100
@@ -478,46 +478,6 @@
         raise HTTPFound(location=url('edit_repo_advanced', repo_name=repo_name))
 
     @HasRepoPermissionLevelDecorator('admin')
-    def edit_advanced_locking(self, repo_name):
-        """
-        Unlock repository when it is locked !
-
-        :param repo_name:
-        """
-        try:
-            repo = Repository.get_by_repo_name(repo_name)
-            if request.POST.get('set_lock'):
-                Repository.lock(repo, request.authuser.user_id)
-                h.flash(_('Repository has been locked'), category='success')
-            elif request.POST.get('set_unlock'):
-                Repository.unlock(repo)
-                h.flash(_('Repository has been unlocked'), category='success')
-        except Exception as e:
-            log.error(traceback.format_exc())
-            h.flash(_('An error occurred during unlocking'),
-                    category='error')
-        raise HTTPFound(location=url('edit_repo_advanced', repo_name=repo_name))
-
-    @HasRepoPermissionLevelDecorator('write')
-    def toggle_locking(self, repo_name):
-        try:
-            repo = Repository.get_by_repo_name(repo_name)
-
-            if repo.enable_locking:
-                if repo.locked[0]:
-                    Repository.unlock(repo)
-                    h.flash(_('Repository has been unlocked'), category='success')
-                else:
-                    Repository.lock(repo, request.authuser.user_id)
-                    h.flash(_('Repository has been locked'), category='success')
-
-        except Exception as e:
-            log.error(traceback.format_exc())
-            h.flash(_('An error occurred during unlocking'),
-                    category='error')
-        raise HTTPFound(location=url('summary_home', repo_name=repo_name))
-
-    @HasRepoPermissionLevelDecorator('admin')
     def edit_caches(self, repo_name):
         c.repo_info = self._load_repo()
         c.active = 'caches'
--- a/kallithea/controllers/api/api.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/controllers/api/api.py	Wed Jan 16 02:32:35 2019 +0100
@@ -303,168 +303,6 @@
                 'Error occurred during cache invalidation action'
             )
 
-    # permission check inside
-    def lock(self, repoid, locked=Optional(None),
-             userid=Optional(OAttr('apiuser'))):
-        """
-        Set locking state on given repository by given user. If userid param
-        is skipped, then it is set to id of user who is calling this method.
-        If locked param is skipped then function shows current lock state of
-        given repo. This command can be executed only using api_key belonging
-        to user with admin rights or regular user that have admin or write
-        access to repository.
-
-        :param repoid: repository name or repository id
-        :type repoid: str or int
-        :param locked: lock state to be set
-        :type locked: Optional(bool)
-        :param userid: set lock as user
-        :type userid: Optional(str or int)
-
-        OUTPUT::
-
-          id : <id_given_in_input>
-          result : {
-            'repo': '<reponame>',
-            'locked': <bool: lock state>,
-            'locked_since': <int: lock timestamp>,
-            'locked_by': <username of person who made the lock>,
-            'lock_state_changed': <bool: True if lock state has been changed in this request>,
-            'msg': 'Repo `<reponame>` locked by `<username>` on <timestamp>.'
-            or
-            'msg': 'Repo `<repository name>` not locked.'
-            or
-            'msg': 'User `<user name>` set lock state for repo `<repository name>` to `<new lock state>`'
-          }
-          error :  null
-
-        ERROR OUTPUT::
-
-          id : <id_given_in_input>
-          result : null
-          error :  {
-            'Error occurred locking repository `<reponame>`
-          }
-
-        """
-        repo = get_repo_or_error(repoid)
-        if HasPermissionAny('hg.admin')():
-            pass
-        elif HasRepoPermissionLevel('write')(repo.repo_name):
-            # make sure normal user does not pass someone else userid,
-            # he is not allowed to do that
-            if not isinstance(userid, Optional) and userid != request.authuser.user_id:
-                raise JSONRPCError(
-                    'userid is not the same as your user'
-                )
-        else:
-            raise JSONRPCError('repository `%s` does not exist' % (repoid,))
-
-        if isinstance(userid, Optional):
-            userid = request.authuser.user_id
-
-        user = get_user_or_error(userid)
-
-        if isinstance(locked, Optional):
-            lockobj = Repository.getlock(repo)
-
-            if lockobj[0] is None:
-                _d = {
-                    'repo': repo.repo_name,
-                    'locked': False,
-                    'locked_since': None,
-                    'locked_by': None,
-                    'lock_state_changed': False,
-                    'msg': 'Repo `%s` not locked.' % repo.repo_name
-                }
-                return _d
-            else:
-                userid, time_ = lockobj
-                lock_user = get_user_or_error(userid)
-                _d = {
-                    'repo': repo.repo_name,
-                    'locked': True,
-                    'locked_since': time_,
-                    'locked_by': lock_user.username,
-                    'lock_state_changed': False,
-                    'msg': ('Repo `%s` locked by `%s` on `%s`.'
-                            % (repo.repo_name, lock_user.username,
-                               json.dumps(time_to_datetime(time_))))
-                }
-                return _d
-
-        # force locked state through a flag
-        else:
-            locked = str2bool(locked)
-            try:
-                if locked:
-                    lock_time = time.time()
-                    Repository.lock(repo, user.user_id, lock_time)
-                else:
-                    lock_time = None
-                    Repository.unlock(repo)
-                _d = {
-                    'repo': repo.repo_name,
-                    'locked': locked,
-                    'locked_since': lock_time,
-                    'locked_by': user.username,
-                    'lock_state_changed': True,
-                    'msg': ('User `%s` set lock state for repo `%s` to `%s`'
-                            % (user.username, repo.repo_name, locked))
-                }
-                return _d
-            except Exception:
-                log.error(traceback.format_exc())
-                raise JSONRPCError(
-                    'Error occurred locking repository `%s`' % repo.repo_name
-                )
-
-    def get_locks(self, userid=Optional(OAttr('apiuser'))):
-        """
-        Get all repositories with locks for given userid, if
-        this command is run by non-admin account userid is set to user
-        who is calling this method, thus returning locks for himself.
-
-        :param userid: User to get locks for
-        :type userid: Optional(str or int)
-
-        OUTPUT::
-
-          id : <id_given_in_input>
-          result : {
-            [repo_object, repo_object,...]
-          }
-          error :  null
-        """
-
-        if not HasPermissionAny('hg.admin')():
-            # make sure normal user does not pass someone else userid,
-            # he is not allowed to do that
-            if not isinstance(userid, Optional) and userid != request.authuser.user_id:
-                raise JSONRPCError(
-                    'userid is not the same as your user'
-                )
-
-        ret = []
-        if isinstance(userid, Optional):
-            user = None
-        else:
-            user = get_user_or_error(userid)
-
-        # show all locks
-        for r in Repository.query():
-            userid, time_ = r.locked
-            if time_:
-                _api_data = r.get_api_data()
-                # if we use userfilter just show the locks for this user
-                if user is not None:
-                    if safe_int(userid) == user.user_id:
-                        ret.append(_api_data)
-                else:
-                    ret.append(_api_data)
-
-        return ret
-
     @HasPermissionAnyDecorator('hg.admin')
     def get_ip(self, userid=Optional(OAttr('apiuser'))):
         """
@@ -1155,7 +993,6 @@
                 "repo_type" :        "<repo_type>",
                 "clone_uri" :        "<clone_uri>",
                 "enable_downloads":  "<bool>",
-                "enable_locking":    "<bool>",
                 "enable_statistics": "<bool>",
                 "private":           "<bool>",
                 "created_on" :       "<date_time_created>",
@@ -1266,7 +1103,6 @@
                         "owner":             "<repo_owner>",
                         "fork_of":           "<name_of_fork_parent>",
                         "enable_downloads":  "<bool>",
-                        "enable_locking":    "<bool>",
                         "enable_statistics": "<bool>",
                       },

@@ -1346,7 +1182,6 @@
                     private=Optional(False), clone_uri=Optional(None),
                     landing_rev=Optional('rev:tip'),
                     enable_statistics=Optional(False),
-                    enable_locking=Optional(False),
                     enable_downloads=Optional(False),
                     copy_permissions=Optional(False)):
         """
@@ -1371,8 +1206,6 @@
         :type clone_uri: str
         :param landing_rev: <rev_type>:<rev>
         :type landing_rev: str
-        :param enable_locking:
-        :type enable_locking: bool
         :param enable_downloads:
         :type enable_downloads: bool
         :param enable_statistics:
@@ -1421,8 +1254,6 @@
             repo_type = defs.get('repo_type')
         if isinstance(enable_statistics, Optional):
             enable_statistics = defs.get('repo_enable_statistics')
-        if isinstance(enable_locking, Optional):
-            enable_locking = defs.get('repo_enable_locking')
         if isinstance(enable_downloads, Optional):
             enable_downloads = defs.get('repo_enable_downloads')
 
@@ -1450,7 +1281,6 @@
                 repo_group=repo_group,
                 repo_landing_rev=landing_rev,
                 enable_statistics=enable_statistics,
-                enable_locking=enable_locking,
                 enable_downloads=enable_downloads,
                 repo_copy_permissions=copy_permissions,
             )
@@ -1476,7 +1306,6 @@
                     description=Optional(''), private=Optional(False),
                     clone_uri=Optional(None), landing_rev=Optional('rev:tip'),
                     enable_statistics=Optional(False),
-                    enable_locking=Optional(False),
                     enable_downloads=Optional(False)):
 
         """
@@ -1492,7 +1321,6 @@
         :param clone_uri:
         :param landing_rev:
         :param enable_statistics:
-        :param enable_locking:
         :param enable_downloads:
         """
         repo = get_repo_or_error(repoid)
@@ -1525,7 +1353,6 @@
             store_update(updates, clone_uri, 'clone_uri')
             store_update(updates, landing_rev, 'repo_landing_rev')
             store_update(updates, enable_statistics, 'repo_enable_statistics')
-            store_update(updates, enable_locking, 'repo_enable_locking')
             store_update(updates, enable_downloads, 'repo_enable_downloads')
 
             RepoModel().update(repo, **updates)
@@ -2020,7 +1847,7 @@
     def update_repo_group(self, repogroupid, group_name=Optional(''),
                           description=Optional(''),
                           owner=Optional(OAttr('apiuser')),
-                          parent=Optional(None), enable_locking=Optional(False)):
+                          parent=Optional(None)):
         repo_group = get_repo_group_or_error(repogroupid)
 
         updates = {}
@@ -2029,7 +1856,6 @@
             store_update(updates, description, 'group_description')
             store_update(updates, owner, 'owner')
             store_update(updates, parent, 'parent_group')
-            store_update(updates, enable_locking, 'enable_locking')
             repo_group = RepoGroupModel().update(repo_group, updates)
             Session().commit()
             return dict(
--- a/kallithea/controllers/files.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/controllers/files.py	Wed Jan 16 02:32:35 2019 +0100
@@ -295,14 +295,6 @@
     @HasRepoPermissionLevelDecorator('write')
     def delete(self, repo_name, revision, f_path):
         repo = c.db_repo
-        if repo.enable_locking and repo.locked[0]:
-            h.flash(_('This repository has been locked by %s on %s')
-                % (h.person_by_id(repo.locked[0]),
-                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
-                'warning')
-            raise HTTPFound(location=h.url('files_home',
-                                  repo_name=repo_name, revision='tip'))
-
         # check if revision is a branch identifier- basically we cannot
         # create multiple heads via file editing
         _branches = repo.scm_instance.branches
@@ -355,14 +347,6 @@
     @HasRepoPermissionLevelDecorator('write')
     def edit(self, repo_name, revision, f_path):
         repo = c.db_repo
-        if repo.enable_locking and repo.locked[0]:
-            h.flash(_('This repository has been locked by %s on %s')
-                % (h.person_by_id(repo.locked[0]),
-                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
-                'warning')
-            raise HTTPFound(location=h.url('files_home',
-                                  repo_name=repo_name, revision='tip'))
-
         # check if revision is a branch identifier- basically we cannot
         # create multiple heads via file editing
         _branches = repo.scm_instance.branches
@@ -422,14 +406,6 @@
     def add(self, repo_name, revision, f_path):
 
         repo = c.db_repo
-        if repo.enable_locking and repo.locked[0]:
-            h.flash(_('This repository has been locked by %s on %s')
-                % (h.person_by_id(repo.locked[0]),
-                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
-                  'warning')
-            raise HTTPFound(location=h.url('files_home',
-                                  repo_name=repo_name, revision='tip'))
-
         r_post = request.POST
         c.cs = self.__get_cs(revision, silent_empty=True)
         if c.cs is None:
--- a/kallithea/lib/base.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/base.py	Wed Jan 16 02:32:35 2019 +0100
@@ -147,42 +147,6 @@
     return auth_user
 
 
-def check_locking_state(action, repo_name, user):
-    """
-    Checks locking on this repository, if locking is enabled, and if lock
-    is present. Returns a tuple of make_lock, locked, locked_by. make_lock
-    can have 3 states: None (do nothing), True (make lock), and False
-    (release lock). This value is later propagated to hooks, telling them
-    what to do.
-    """
-    locked = False  # defines that locked error should be thrown to user
-    make_lock = None
-    repo = Repository.get_by_repo_name(repo_name)
-    locked_by = repo.locked
-    if repo and repo.enable_locking:
-        if action == 'push':
-            # Check if repo already is locked !, if it is compare users
-            user_id, _date = locked_by
-            if user.user_id == user_id:
-                log.debug('Got push from user %s, now unlocking', user)
-                # Unlock if we have push from the user who locked
-                make_lock = False
-            else:
-                # Another used tried to push - deny access with something like 423 Locked!
-                locked = True
-        if action == 'pull':
-            if repo.locked[0] and repo.locked[1]:
-                locked = True
-            else:
-                log.debug('Setting lock on repo %s by %s', repo, user)
-                make_lock = True
-    else:
-        log.debug('Repository %s does not have locking enabled', repo)
-    log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s',
-              make_lock, locked, locked_by)
-    return make_lock, locked, locked_by
-
-
 class BasicAuth(paste.auth.basic.AuthBasicAuthenticator):
 
     def __init__(self, realm, authfunc, auth_http_code=None):
--- a/kallithea/lib/celerylib/tasks.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/celerylib/tasks.py	Wed Jan 16 02:32:35 2019 +0100
@@ -349,7 +349,6 @@
     # repo creation defaults, private and repo_type are filled in form
     defs = Setting.get_default_repo_settings(strip_prefix=True)
     enable_statistics = defs.get('repo_enable_statistics')
-    enable_locking = defs.get('repo_enable_locking')
     enable_downloads = defs.get('repo_enable_downloads')
 
     try:
@@ -366,7 +365,6 @@
             copy_fork_permissions=copy_fork_permissions,
             copy_group_permissions=copy_group_permissions,
             enable_statistics=enable_statistics,
-            enable_locking=enable_locking,
             enable_downloads=enable_downloads,
             state=state
         )
--- a/kallithea/lib/db_manage.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/db_manage.py	Wed Jan 16 02:32:35 2019 +0100
@@ -240,7 +240,6 @@
         """Creates default settings"""
 
         for k, v, t in [
-            ('default_repo_enable_locking',  False, 'bool'),
             ('default_repo_enable_downloads', False, 'bool'),
             ('default_repo_enable_statistics', False, 'bool'),
             ('default_repo_private', False, 'bool'),
@@ -354,9 +353,7 @@
             ('hooks', Ui.HOOK_UPDATE, 'hg update >&2', False),
             ('hooks', Ui.HOOK_REPO_SIZE, 'python:kallithea.lib.hooks.repo_size', True),
             ('hooks', Ui.HOOK_PUSH_LOG, 'python:kallithea.lib.hooks.log_push_action', True),
-            ('hooks', Ui.HOOK_PUSH_LOCK, 'python:kallithea.lib.hooks.push_lock_handling', True),
             ('hooks', Ui.HOOK_PULL_LOG, 'python:kallithea.lib.hooks.log_pull_action', True),
-            ('hooks', Ui.HOOK_PULL_LOCK, 'python:kallithea.lib.hooks.pull_lock_handling', True),
             ('extensions', 'largefiles', '', True),
             ('largefiles', 'usercache', os.path.join(path, '.cache', 'largefiles'), True),
             ('extensions', 'hgsubversion', '', False),
--- a/kallithea/lib/exceptions.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/exceptions.py	Wed Jan 16 02:32:35 2019 +0100
@@ -71,24 +71,6 @@
     pass
 
 
-class HTTPLockedRC(HTTPClientError):
-    """
-    Special Exception For locked Repos in Kallithea, the return code can
-    be overwritten by _code keyword argument passed into constructors
-    """
-    code = 423
-    title = explanation = 'Repository Locked'
-
-    def __init__(self, reponame, username, *args, **kwargs):
-        from kallithea import CONFIG
-        from kallithea.lib.utils2 import safe_int
-        _code = CONFIG.get('lock_ret_code')
-        self.code = safe_int(_code, self.code)
-        self.title = self.explanation = safe_str(
-            'Repository `%s` locked by user `%s`' % (reponame, username))
-        super(HTTPLockedRC, self).__init__(*args, **kwargs)
-
-
 class IMCCommitError(Exception):
     pass
 
--- a/kallithea/lib/hooks.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/hooks.py	Wed Jan 16 02:32:35 2019 +0100
@@ -33,7 +33,7 @@
 from kallithea.lib import helpers as h
 from kallithea.lib.utils import action_logger
 from kallithea.lib.vcs.backends.base import EmptyChangeset
-from kallithea.lib.exceptions import HTTPLockedRC, UserCreationError
+from kallithea.lib.exceptions import UserCreationError
 from kallithea.lib.utils import make_ui, setup_cache_regions
 from kallithea.lib.utils2 import safe_str, safe_unicode, _extract_extras
 from kallithea.model.db import Repository, User, Ui
@@ -78,44 +78,8 @@
     ui.status(msg)
 
 
-def push_lock_handling(ui, repo, **kwargs):
-    """Pre push function, currently used to ban pushing when repository is locked.
-
-    Called as Mercurial hook prechangegroup.push_lock_handling or from the Git pre-receive hook calling handle_git_pre_receive.
-    """
-    ex = _extract_extras()
-
-    usr = User.get_by_username(ex.username)
-    if ex.locked_by[0] and usr.user_id != int(ex.locked_by[0]):
-        locked_by = User.get(ex.locked_by[0]).username
-        # this exception is interpreted in git/hg middlewares and based
-        # on that proper return code is server to client
-        _http_ret = HTTPLockedRC(ex.repository, locked_by)
-        if str(_http_ret.code).startswith('2'):
-            # 2xx Codes don't raise exceptions
-            ui.status(safe_str(_http_ret.title))
-        else:
-            raise _http_ret
-
-
-def pull_lock_handling(ui, repo, **kwargs):
-    """Called as Mercurial hook preoutgoing.pull_lock_handling or from Kallithea before invoking Git"""
-    # pre pull function ...
-    ex = _extract_extras()
-    if ex.locked_by[0]:
-        locked_by = User.get(ex.locked_by[0]).username
-        # this exception is interpreted in git/hg middlewares and based
-        # on that proper return code is server to client
-        _http_ret = HTTPLockedRC(ex.repository, locked_by)
-        if str(_http_ret.code).startswith('2'):
-            # 2xx Codes don't raise exceptions
-            ui.status(safe_str(_http_ret.title))
-        else:
-            raise _http_ret
-
-
 def log_pull_action(ui, repo, **kwargs):
-    """Logs user last pull action, and also handle locking
+    """Logs user last pull action
 
     Called as Mercurial hook outgoing.pull_logger or from Kallithea before invoking Git.
     """
@@ -132,17 +96,6 @@
         kw.update(ex)
         callback(**kw)
 
-    if ex.make_lock is not None and ex.make_lock:
-        Repository.lock(Repository.get_by_repo_name(ex.repository), user.user_id)
-        #msg = 'Made lock on repo `%s`' % repository
-        #ui.status(msg)
-
-    if ex.locked_by[0]:
-        locked_by = User.get(ex.locked_by[0]).username
-        _http_ret = HTTPLockedRC(ex.repository, locked_by)
-        if str(_http_ret.code).startswith('2'):
-            # 2xx Codes don't raise exceptions
-            ui.status(safe_str(_http_ret.title))
     return 0
 
 
@@ -196,17 +149,6 @@
         kw.update(ex)
         callback(**kw)
 
-    if ex.make_lock is not None and not ex.make_lock:
-        Repository.unlock(Repository.get_by_repo_name(ex.repository))
-        ui.status(safe_str('Released lock on repo `%s`\n' % ex.repository))
-
-    if ex.locked_by[0]:
-        locked_by = User.get(ex.locked_by[0]).username
-        _http_ret = HTTPLockedRC(ex.repository, locked_by)
-        if str(_http_ret.code).startswith('2'):
-            # 2xx Codes don't raise exceptions
-            ui.status(safe_str(_http_ret.title))
-
     return 0
 
 
@@ -406,9 +348,6 @@
 
 def handle_git_pre_receive(repo_path, git_stdin_lines):
     """Called from Git pre-receive hook"""
-    baseui, repo = _hook_environment(repo_path)
-    scm_repo = repo.scm_instance
-    push_lock_handling(baseui, scm_repo)
     return 0
 
 
--- a/kallithea/lib/middleware/simplegit.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/middleware/simplegit.py	Wed Jan 16 02:32:35 2019 +0100
@@ -39,10 +39,8 @@
 
 from kallithea.lib.utils2 import safe_str, safe_unicode, fix_PATH, get_server_url, \
     _set_extras
-from kallithea.lib.base import BaseVCSController, check_locking_state
+from kallithea.lib.base import BaseVCSController
 from kallithea.lib.utils import make_ui, is_valid_repo
-from kallithea.lib.exceptions import HTTPLockedRC
-from kallithea.lib.hooks import pull_lock_handling
 
 log = logging.getLogger(__name__)
 
@@ -110,8 +108,6 @@
             'scm': 'git',
             'config': CONFIG['__file__'],
             'server_url': server_url,
-            'make_lock': None,
-            'locked_by': [None, None]
         }
 
         #===================================================================
@@ -120,13 +116,6 @@
         repo_path = os.path.join(safe_str(self.basepath), str_repo_name)
         log.debug('Repository path is %s', repo_path)
 
-        if not user.is_default_user:
-            log.debug('Checking locking on repository')
-            make_lock, locked, locked_by = check_locking_state(action, repo_name, user)
-            # store the make_lock for later evaluation in hooks
-            extras.update({'make_lock': make_lock,
-                           'locked_by': locked_by})
-
         fix_PATH()
         log.debug('HOOKS extras is %s', extras)
         baseui = make_ui('db')
@@ -138,9 +127,6 @@
                      action, str_repo_name, safe_str(user.username), ip_addr)
             app = self.__make_app(repo_name, repo_path, extras)
             return app(environ, start_response)
-        except HTTPLockedRC as e:
-            log.debug('Locked, response %s: %s', e.code, e.title)
-            return e(environ, start_response)
         except Exception:
             log.error(traceback.format_exc())
             return HTTPInternalServerError()(environ, start_response)
@@ -211,8 +197,5 @@
         _repo = _repo.scm_instance
 
         _hooks = dict(baseui.configitems('hooks')) or {}
-        if action == 'pull':
-            # stupid git, emulate pre-pull hook !
-            pull_lock_handling(ui=baseui, repo=_repo._repo)
         if action == 'pull' and _hooks.get(Ui.HOOK_PULL_LOG):
             log_pull_action(ui=baseui, repo=_repo._repo)
--- a/kallithea/lib/middleware/simplehg.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/middleware/simplehg.py	Wed Jan 16 02:32:35 2019 +0100
@@ -38,10 +38,9 @@
 
 from kallithea.lib.utils2 import safe_str, safe_unicode, fix_PATH, get_server_url, \
     _set_extras
-from kallithea.lib.base import BaseVCSController, check_locking_state
+from kallithea.lib.base import BaseVCSController
 from kallithea.lib.utils import make_ui, is_valid_repo, ui_sections
 from kallithea.lib.vcs.utils.hgcompat import RepoError, hgweb_mod
-from kallithea.lib.exceptions import HTTPLockedRC
 
 log = logging.getLogger(__name__)
 
@@ -134,8 +133,6 @@
             'scm': 'hg',
             'config': CONFIG['__file__'],
             'server_url': server_url,
-            'make_lock': None,
-            'locked_by': [None, None]
         }
         #======================================================================
         # MERCURIAL REQUEST HANDLING
@@ -143,19 +140,6 @@
         repo_path = os.path.join(safe_str(self.basepath), str_repo_name)
         log.debug('Repository path is %s', repo_path)
 
-        # A Mercurial HTTP server will see listkeys operations (bookmarks,
-        # phases and obsolescence marker) in a different request - we don't
-        # want to check locking on those
-        if environ['QUERY_STRING'] == 'cmd=listkeys':
-            pass
-        # CHECK LOCKING only if it's not ANONYMOUS USER
-        elif not user.is_default_user:
-            log.debug('Checking locking on repository')
-            make_lock, locked, locked_by = check_locking_state(action, repo_name, user)
-            # store the make_lock for later evaluation in hooks
-            extras.update({'make_lock': make_lock,
-                           'locked_by': locked_by})
-
         fix_PATH()
         log.debug('HOOKS extras is %s', extras)
         baseui = make_ui('db')
@@ -171,10 +155,6 @@
         except RepoError as e:
             if str(e).find('not found') != -1:
                 return HTTPNotFound()(environ, start_response)
-        except HTTPLockedRC as e:
-            # Before Mercurial 3.6, lock exceptions were caught here
-            log.debug('Locked, response %s: %s', e.code, e.title)
-            return e(environ, start_response)
         except Exception:
             log.error(traceback.format_exc())
             return HTTPInternalServerError()(environ, start_response)
@@ -184,26 +164,7 @@
         Make an wsgi application using hgweb, and inject generated baseui
         instance, additionally inject some extras into ui object
         """
-        class HgWebWrapper(hgweb_mod.hgweb):
-            # Work-around for Mercurial 3.6+ causing lock exceptions to be
-            # thrown late
-            def _runwsgi(self, *args):
-                try:
-                    return super(HgWebWrapper, self)._runwsgi(*args)
-                except HTTPLockedRC as e:
-                    log.debug('Locked, response %s: %s', e.code, e.title)
-                    try:
-                        req, res, repo = args
-                        res.status = e.status
-                        res.headers['Content-Type'] = 'text/plain'
-                        res.setbodybytes('')
-                        return res.sendresponse()
-                    except ValueError: # wsgiresponse was introduced in Mercurial 4.6 (a88d68dc3ee8)
-                        req, repo = args
-                        req.respond(e.status, 'text/plain')
-                        return ''
-
-        return HgWebWrapper(repo_name, name=repo_name, baseui=baseui)
+        return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui)
 
     def __get_repository(self, environ):
         """
--- a/kallithea/lib/paster_commands/template.ini.mako	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/paster_commands/template.ini.mako	Wed Jan 16 02:32:35 2019 +0100
@@ -316,10 +316,6 @@
 <%text>## handling that. Set this variable to 403 to return HTTPForbidden</%text>
 auth_ret_code =
 
-<%text>## locking return code. When repository is locked return this HTTP code. 2XX</%text>
-<%text>## codes don't break the transactions while 4XX codes do</%text>
-lock_ret_code = 423
-
 <%text>## allows to change the repository location in settings page</%text>
 allow_repo_location_change = True
 
--- a/kallithea/lib/utils.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/utils.py	Wed Jan 16 02:32:35 2019 +0100
@@ -481,7 +481,6 @@
     # creation defaults
     defs = Setting.get_default_repo_settings(strip_prefix=True)
     enable_statistics = defs.get('repo_enable_statistics')
-    enable_locking = defs.get('repo_enable_locking')
     enable_downloads = defs.get('repo_enable_downloads')
     private = defs.get('repo_private')
 
@@ -503,7 +502,6 @@
                 description=desc,
                 repo_group=getattr(group, 'group_id', None),
                 owner=user,
-                enable_locking=enable_locking,
                 enable_downloads=enable_downloads,
                 enable_statistics=enable_statistics,
                 private=private,
--- a/kallithea/lib/utils2.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/lib/utils2.py	Wed Jan 16 02:32:35 2019 +0100
@@ -549,8 +549,7 @@
         raise Exception("Environment variable KALLITHEA_EXTRAS not found")
 
     try:
-        for k in ['username', 'repository', 'locked_by', 'scm', 'make_lock',
-                  'action', 'ip']:
+        for k in ['username', 'repository', 'scm', 'action', 'ip']:
             extras[k]
     except KeyError:
         raise Exception('Missing key %s in KALLITHEA_EXTRAS %s' % (k, extras))
--- a/kallithea/model/db.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/db.py	Wed Jan 16 02:32:35 2019 +0100
@@ -352,9 +352,7 @@
     HOOK_UPDATE = 'changegroup.update'
     HOOK_REPO_SIZE = 'changegroup.repo_size'
     HOOK_PUSH_LOG = 'changegroup.push_logger'
-    HOOK_PUSH_LOCK = 'prechangegroup.push_lock_handling'
     HOOK_PULL_LOG = 'outgoing.pull_logger'
-    HOOK_PULL_LOCK = 'preoutgoing.pull_lock_handling'
 
     ui_id = Column(Integer(), primary_key=True)
     ui_section = Column(String(255), nullable=False)
@@ -380,8 +378,7 @@
     def get_builtin_hooks(cls):
         q = cls.query()
         q = q.filter(cls.ui_key.in_([cls.HOOK_UPDATE, cls.HOOK_REPO_SIZE,
-                                     cls.HOOK_PUSH_LOG, cls.HOOK_PUSH_LOCK,
-                                     cls.HOOK_PULL_LOG, cls.HOOK_PULL_LOCK]))
+                                     cls.HOOK_PUSH_LOG, cls.HOOK_PULL_LOG]))
         q = q.filter(cls.ui_section == 'hooks')
         return q.all()
 
@@ -389,8 +386,7 @@
     def get_custom_hooks(cls):
         q = cls.query()
         q = q.filter(~cls.ui_key.in_([cls.HOOK_UPDATE, cls.HOOK_REPO_SIZE,
-                                      cls.HOOK_PUSH_LOG, cls.HOOK_PUSH_LOCK,
-                                      cls.HOOK_PULL_LOG, cls.HOOK_PULL_LOCK]))
+                                      cls.HOOK_PUSH_LOG, cls.HOOK_PULL_LOG]))
         q = q.filter(cls.ui_section == 'hooks')
         return q.all()
 
@@ -994,8 +990,6 @@
     created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
     updated_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
     _landing_revision = Column("landing_revision", String(255), nullable=False)
-    enable_locking = Column(Boolean(), nullable=False, default=False)
-    _locked = Column("locked", String(255), nullable=True) # FIXME: not nullable?
     _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data # FIXME: not nullable?
 
     fork_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=True)
@@ -1047,21 +1041,6 @@
         self._landing_revision = val
 
     @hybrid_property
-    def locked(self):
-        # always should return [user_id, timelocked]
-        if self._locked:
-            _lock_info = self._locked.split(':')
-            return int(_lock_info[0]), _lock_info[1]
-        return [None, None]
-
-    @locked.setter
-    def locked(self, val):
-        if val and isinstance(val, (list, tuple)):
-            self._locked = ':'.join(map(str, val))
-        else:
-            self._locked = None
-
-    @hybrid_property
     def changeset_cache(self):
         try:
             cs_cache = json.loads(self._changeset_cache) # might raise on bad data
@@ -1254,13 +1233,8 @@
             owner=repo.owner.username,
             fork_of=repo.fork.repo_name if repo.fork else None,
             enable_statistics=repo.enable_statistics,
-            enable_locking=repo.enable_locking,
             enable_downloads=repo.enable_downloads,
             last_changeset=repo.changeset_cache,
-            locked_by=User.get(self.locked[0]).get_api_data() \
-                if self.locked[0] else None,
-            locked_date=time_to_datetime(self.locked[1]) \
-                if self.locked[1] else None
         )
         if with_revision_names:
             scm_repo = repo.scm_instance_no_cache()
@@ -1279,22 +1253,6 @@
 
         return data
 
-    @classmethod
-    def lock(cls, repo, user_id, lock_time=None):
-        if lock_time is not None:
-            lock_time = time.time()
-        repo.locked = [user_id, lock_time]
-        Session().commit()
-
-    @classmethod
-    def unlock(cls, repo):
-        repo.locked = None
-        Session().commit()
-
-    @classmethod
-    def getlock(cls, repo):
-        return repo.locked
-
     @property
     def last_db_change(self):
         return self.updated_on
@@ -1524,7 +1482,6 @@
     group_name = Column(Unicode(255), nullable=False, unique=True) # full path
     parent_group_id = Column('group_parent_id', Integer(), ForeignKey('groups.group_id'), nullable=True)
     group_description = Column(Unicode(10000), nullable=False)
-    enable_locking = Column(Boolean(), nullable=False, default=False)
     owner_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
     created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
--- a/kallithea/model/forms.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/forms.py	Wed Jan 16 02:32:35 2019 +0100
@@ -182,7 +182,6 @@
                                       testValueList=True,
                                       if_missing=None, not_empty=True),
                               v.Int(min=-1, not_empty=True))
-        enable_locking = v.StringBoolean(if_missing=False)
         chained_validators = [v.ValidRepoGroup(edit, old_data)]
 
     return _RepoGroupForm
@@ -264,7 +263,6 @@
 
         repo_enable_statistics = v.StringBoolean(if_missing=False)
         repo_enable_downloads = v.StringBoolean(if_missing=False)
-        repo_enable_locking = v.StringBoolean(if_missing=False)
 
         if edit:
             owner = All(v.UnicodeString(not_empty=True), v.ValidRepoUser())
@@ -447,7 +445,6 @@
         default_repo_private = v.StringBoolean(if_missing=False)
         default_repo_enable_statistics = v.StringBoolean(if_missing=False)
         default_repo_enable_downloads = v.StringBoolean(if_missing=False)
-        default_repo_enable_locking = v.StringBoolean(if_missing=False)
 
     return _DefaultsForm
 
--- a/kallithea/model/repo.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/repo.py	Wed Jan 16 02:32:35 2019 +0100
@@ -236,7 +236,7 @@
         defaults['repo_group'] = repo_info.group_id
 
         for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
-                         (1, 'repo_description'), (1, 'repo_enable_locking'),
+                         (1, 'repo_description'),
                          (1, 'repo_landing_rev'), (0, 'clone_uri'),
                          (1, 'repo_private'), (1, 'repo_enable_statistics')]:
             attr = k
@@ -284,7 +284,6 @@
             log.debug('Updating repo %s with params:%s', cur_repo, kwargs)
             for k in ['repo_enable_downloads',
                       'repo_description',
-                      'repo_enable_locking',
                       'repo_landing_rev',
                       'repo_private',
                       'repo_enable_statistics',
@@ -332,7 +331,7 @@
                      private=False, clone_uri=None, repo_group=None,
                      landing_rev='rev:tip', fork_of=None,
                      copy_fork_permissions=False, enable_statistics=False,
-                     enable_locking=False, enable_downloads=False,
+                     enable_downloads=False,
                      copy_group_permissions=False, state=Repository.STATE_PENDING):
         """
         Create repository inside database with PENDING state. This should only be
@@ -371,12 +370,8 @@
             new_repo.landing_rev = landing_rev
 
             new_repo.enable_statistics = enable_statistics
-            new_repo.enable_locking = enable_locking
             new_repo.enable_downloads = enable_downloads
 
-            if repo_group:
-                new_repo.enable_locking = repo_group.enable_locking
-
             if fork_of:
                 parent_repo = fork_of
                 new_repo.fork = parent_repo
--- a/kallithea/model/repo_group.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/repo_group.py	Wed Jan 16 02:32:35 2019 +0100
@@ -287,8 +287,6 @@
                 repo_group.group_description = repo_group_args['group_description']
             if 'parent_group_id' in repo_group_args:
                 repo_group.parent_group_id = repo_group_args['parent_group_id']
-            if 'enable_locking' in repo_group_args:
-                repo_group.enable_locking = repo_group_args['enable_locking']
 
             if 'parent_group_id' in repo_group_args:
                 assert repo_group_args['parent_group_id'] != u'-1', repo_group_args  # RepoGroupForm should have converted to None
@@ -302,14 +300,12 @@
             Session().add(repo_group)
 
             # iterate over all members of this groups and do fixes
-            # set locking if given
             # if obj is a repoGroup also fix the name of the group according
             # to the parent
             # if obj is a Repo fix it's name
             # this can be potentially heavy operation
             for obj in repo_group.recursive_groups_and_repos():
                 # set the value from it's parent
-                obj.enable_locking = repo_group.enable_locking
                 if isinstance(obj, RepoGroup):
                     new_name = obj.get_new_name(obj.name)
                     log.debug('Fixing group %s to new name %s' \
--- a/kallithea/model/scm.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/scm.py	Wed Jan 16 02:32:35 2019 +0100
@@ -348,8 +348,6 @@
             'scm': repo_alias,
             'config': CONFIG['__file__'],
             'server_url': get_server_url(environ),
-            'make_lock': None,
-            'locked_by': [None, None]
         }
         _set_extras(extras)
 
--- a/kallithea/model/validators.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/model/validators.py	Wed Jan 16 02:32:35 2019 +0100
@@ -625,7 +625,7 @@
             # with forms
 
             forbidden_params = [
-                'user', 'repo_type', 'repo_enable_locking',
+                'user', 'repo_type',
                 'repo_enable_downloads', 'repo_enable_statistics'
             ]
 
--- a/kallithea/templates/admin/defaults/defaults.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/admin/defaults/defaults.html	Wed Jan 16 02:32:35 2019 +0100
@@ -55,14 +55,6 @@
             </div>
 
             <div class="form-group">
-                <label class="control-label" for="default_repo_enable_locking">${_('Enable locking')}:</label>
-                <div>
-                    ${h.checkbox('default_repo_enable_locking',value="True")}
-                    <span class="help-block">${_('Enable lock-by-pulling on repository.')}</span>
-                </div>
-            </div>
-
-            <div class="form-group">
                 <div class="buttons">
                     ${h.submit('save',_('Save'),class_="btn btn-default")}
                 </div>
--- a/kallithea/templates/admin/repo_groups/repo_group_edit_settings.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/admin/repo_groups/repo_group_edit_settings.html	Wed Jan 16 02:32:35 2019 +0100
@@ -23,14 +23,6 @@
         </div>
 
         <div class="form-group">
-            <label class="control-label" for="enable_locking">${_('Enable locking')}:</label>
-            <div>
-                ${h.checkbox('enable_locking',value="True")}
-                <span class="help-block">${_('Enable lock-by-pulling on group. This option will be applied to all other groups and repositories inside')}</span>
-            </div>
-        </div>
-
-        <div class="form-group">
             <div class="buttons">
                 ${h.submit('save',_('Save'),class_="btn btn-default")}
                 ${h.reset('reset',_('Reset'),class_="btn btn-default")}
--- a/kallithea/templates/admin/repos/repo_edit_advanced.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/admin/repos/repo_edit_advanced.html	Wed Jan 16 02:32:35 2019 +0100
@@ -39,32 +39,6 @@
 </div>
 ${h.end_form()}
 
-<h3>${_('Change Locking')}</h3>
-${h.form(url('edit_repo_advanced_locking', repo_name=c.repo_info.repo_name))}
-<div class="form">
-      %if c.repo_info.locked[0]:
-        ${h.hidden('set_unlock', '1')}
-        <button class="btn btn-default btn-sm" type="submit"
-                onclick="return confirm('${_('Confirm to unlock repository.')}');">
-            <i class="icon-lock-open-alt"></i>
-            ${_('Unlock Repository')}
-        </button>
-       ${_('Locked by %s on %s') % (h.person_by_id(c.repo_info.locked[0]),h.fmt_date(h.time_to_datetime(c.repo_info.locked[1])))}
-      %else:
-        ${h.hidden('set_lock', '1')}
-        <button class="btn btn-default btn-sm" type="submit"
-                onclick="return confirm('${_('Confirm to lock repository.')}');">
-            <i class="icon-lock"></i>
-            ${_('Lock Repository')}
-        </button>
-        ${_('Repository is not locked')}
-      %endif
-   <div class="text-muted">
-   ${_('Force locking on the repository. Works only when anonymous access is disabled. Triggering a pull locks the repository.  The user who is pulling locks the repository; only the user who pulled and locked it can unlock it by doing a push.')}
-   </div>
-</div>
-${h.end_form()}
-
 <h3>${_('Delete')}</h3>
 ${h.form(url('delete_repo', repo_name=c.repo_name))}
 <div class="form">
--- a/kallithea/templates/admin/repos/repo_edit_settings.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/admin/repos/repo_edit_settings.html	Wed Jan 16 02:32:35 2019 +0100
@@ -74,13 +74,6 @@
                     <span class="help-block">${_('Enable download menu on summary page.')}</span>
                 </div>
             </div>
-            <div class="form-group">
-                <label class="control-label" for="repo_enable_locking">${_('Enable locking')}:</label>
-                <div>
-                    ${h.checkbox('repo_enable_locking',value="True")}
-                    <span class="help-block">${_('Enable lock-by-pulling on repository.')}</span>
-                </div>
-            </div>
 
             %if c.visual.repository_fields:
               ## EXTRA FIELDS
--- a/kallithea/templates/base/base.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/base/base.html	Wed Jan 16 02:32:35 2019 +0100
@@ -159,13 +159,6 @@
 
               <li><a href="${h.url('search_repo',repo_name=c.repo_name)}"><i class="icon-search"></i>${_('Search')}</a></li>
 
-              %if h.HasRepoPermissionLevel('write')(c.repo_name) and c.db_repo.enable_locking:
-                %if c.db_repo.locked[0]:
-                  <li><a href="${h.url('toggle_locking', repo_name=c.repo_name)}"><i class="icon-lock"></i>${_('Unlock')}</a></li>
-                %else:
-                  <li><a href="${h.url('toggle_locking', repo_name=c.repo_name)}"><i class="icon-lock-open-alt"></i>${_('Lock')}</a></li>
-                %endif
-              %endif
               ## TODO: this check feels wrong, it would be better to have a check for permissions
               ## also it feels like a job for the controller
               %if request.authuser.username != 'default':
--- a/kallithea/templates/summary/summary.html	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/templates/summary/summary.html	Wed Jan 16 02:32:35 2019 +0100
@@ -8,15 +8,6 @@
 <%def name="breadcrumbs_links()">
     ${_('Summary')}
 
-    ## locking icon
-    %if c.db_repo.enable_locking:
-     %if c.db_repo.locked[0]:
-       <span class="locking_locked icon-block" data-toggle="tooltip" title="${_('Repository locked by %s') % h.person_by_id(c.db_repo.locked[0])}"></span>
-     %else:
-       <span class="locking_unlocked icon-ok" data-toggle="tooltip" title="${_('Repository unlocked')}"></span>
-     %endif
-    %endif
-
     ##FORK
     %if c.db_repo.fork:
         - <i class="icon-fork"></i>${_('Fork of')} "<a href="${h.url('summary_home',repo_name=c.db_repo.fork.repo_name)}">${c.db_repo.fork.repo_name}</a>"
--- a/kallithea/tests/api/api_base.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/tests/api/api_base.py	Wed Jan 16 02:32:35 2019 +0100
@@ -386,205 +386,6 @@
         expected = "repository `%s` does not exist" % (self.REPO,)
         self._compare_error(id_, expected, given=response.body)
 
-    def test_api_lock_repo_lock_acquire(self):
-        try:
-            id_, params = _build_data(self.apikey, 'lock',
-                                      userid=TEST_USER_ADMIN_LOGIN,
-                                      repoid=self.REPO,
-                                      locked=True)
-            response = api_call(self, params)
-            expected = {
-                'repo': self.REPO, 'locked': True,
-                'locked_since': response.json['result']['locked_since'],
-                'locked_by': TEST_USER_ADMIN_LOGIN,
-                'lock_state_changed': True,
-                'msg': ('User `%s` set lock state for repo `%s` to `%s`'
-                        % (TEST_USER_ADMIN_LOGIN, self.REPO, True))
-            }
-            self._compare_ok(id_, expected, given=response.body)
-        finally:
-            # cleanup
-            Repository.unlock(RepoModel().get_by_repo_name(self.REPO))
-
-    def test_api_lock_repo_lock_acquire_by_non_admin(self):
-        repo_name = u'api_delete_me'
-        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE,
-                            cur_user=self.TEST_USER_LOGIN)
-        try:
-            id_, params = _build_data(self.apikey_regular, 'lock',
-                                      repoid=repo_name,
-                                      locked=True)
-            response = api_call(self, params)
-            expected = {
-                'repo': repo_name,
-                'locked': True,
-                'locked_since': response.json['result']['locked_since'],
-                'locked_by': self.TEST_USER_LOGIN,
-                'lock_state_changed': True,
-                'msg': ('User `%s` set lock state for repo `%s` to `%s`'
-                        % (self.TEST_USER_LOGIN, repo_name, True))
-            }
-            self._compare_ok(id_, expected, given=response.body)
-        finally:
-            fixture.destroy_repo(repo_name)
-
-    def test_api_lock_repo_lock_acquire_non_admin_with_userid(self):
-        repo_name = u'api_delete_me'
-        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE,
-                            cur_user=self.TEST_USER_LOGIN)
-        try:
-            id_, params = _build_data(self.apikey_regular, 'lock',
-                                      userid=TEST_USER_ADMIN_LOGIN,
-                                      repoid=repo_name,
-                                      locked=True)
-            response = api_call(self, params)
-            expected = 'userid is not the same as your user'
-            self._compare_error(id_, expected, given=response.body)
-        finally:
-            fixture.destroy_repo(repo_name)
-
-    def test_api_lock_repo_lock_acquire_non_admin_not_his_repo(self):
-        id_, params = _build_data(self.apikey_regular, 'lock',
-                                  repoid=self.REPO,
-                                  locked=True)
-        response = api_call(self, params)
-        expected = 'repository `%s` does not exist' % (self.REPO)
-        self._compare_error(id_, expected, given=response.body)
-
-    def test_api_lock_repo_lock_release(self):
-        id_, params = _build_data(self.apikey, 'lock',
-                                  userid=TEST_USER_ADMIN_LOGIN,
-                                  repoid=self.REPO,
-                                  locked=False)
-        response = api_call(self, params)
-        expected = {
-            'repo': self.REPO,
-            'locked': False,
-            'locked_since': None,
-            'locked_by': TEST_USER_ADMIN_LOGIN,
-            'lock_state_changed': True,
-            'msg': ('User `%s` set lock state for repo `%s` to `%s`'
-                    % (TEST_USER_ADMIN_LOGIN, self.REPO, False))
-        }
-        self._compare_ok(id_, expected, given=response.body)
-
-        # test_api_lock_repo_lock_optional_not_locked(self):
-        id_, params = _build_data(self.apikey, 'lock',
-                                  repoid=self.REPO)
-        response = api_call(self, params)
-        expected = {
-            'repo': self.REPO,
-            'locked': False,
-            'locked_since': None,
-            'locked_by': None,
-            'lock_state_changed': False,
-            'msg': ('Repo `%s` not locked.' % (self.REPO,))
-        }
-        self._compare_ok(id_, expected, given=response.body)
-
-    def test_api_lock_repo_lock_acquire_optional_userid(self):
-        try:
-            id_, params = _build_data(self.apikey, 'lock',
-                                      repoid=self.REPO,
-                                      locked=True)
-            response = api_call(self, params)
-            time_ = response.json['result']['locked_since']
-            expected = {
-                'repo': self.REPO,
-                'locked': True,
-                'locked_since': time_,
-                'locked_by': TEST_USER_ADMIN_LOGIN,
-                'lock_state_changed': True,
-                'msg': ('User `%s` set lock state for repo `%s` to `%s`'
-                        % (TEST_USER_ADMIN_LOGIN, self.REPO, True))
-            }
-
-            self._compare_ok(id_, expected, given=response.body)
-
-            # test_api_lock_repo_lock_optional_locked
-            id_, params = _build_data(self.apikey, 'lock',
-                                      repoid=self.REPO)
-            response = api_call(self, params)
-            time_ = response.json['result']['locked_since']
-            expected = {
-                'repo': self.REPO,
-                'locked': True,
-                'locked_since': time_,
-                'locked_by': TEST_USER_ADMIN_LOGIN,
-                'lock_state_changed': False,
-                'msg': ('Repo `%s` locked by `%s` on `%s`.'
-                        % (self.REPO, TEST_USER_ADMIN_LOGIN,
-                           json.dumps(time_to_datetime(time_))))
-            }
-            self._compare_ok(id_, expected, given=response.body)
-        finally:
-            # cleanup
-            Repository.unlock(RepoModel().get_by_repo_name(self.REPO))
-
-    @mock.patch.object(Repository, 'lock', crash)
-    def test_api_lock_error(self):
-        id_, params = _build_data(self.apikey, 'lock',
-                                  userid=TEST_USER_ADMIN_LOGIN,
-                                  repoid=self.REPO,
-                                  locked=True)
-        response = api_call(self, params)
-
-        expected = 'Error occurred locking repository `%s`' % self.REPO
-        self._compare_error(id_, expected, given=response.body)
-
-    def test_api_get_locks_regular_user(self):
-        id_, params = _build_data(self.apikey_regular, 'get_locks')
-        response = api_call(self, params)
-        expected = []
-        self._compare_ok(id_, expected, given=response.body)
-
-    def test_api_get_locks_with_userid_regular_user(self):
-        id_, params = _build_data(self.apikey_regular, 'get_locks',
-                                  userid=TEST_USER_ADMIN_LOGIN)
-        response = api_call(self, params)
-        expected = 'userid is not the same as your user'
-        self._compare_error(id_, expected, given=response.body)
-
-    def test_api_get_locks(self):
-        id_, params = _build_data(self.apikey, 'get_locks')
-        response = api_call(self, params)
-        expected = []
-        self._compare_ok(id_, expected, given=response.body)
-
-    def test_api_get_locks_with_one_locked_repo(self):
-        repo_name = u'api_delete_me'
-        repo = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE,
-                                   cur_user=self.TEST_USER_LOGIN)
-        Repository.lock(repo, User.get_by_username(self.TEST_USER_LOGIN).user_id)
-        try:
-            id_, params = _build_data(self.apikey, 'get_locks')
-            response = api_call(self, params)
-            expected = [repo.get_api_data()]
-            self._compare_ok(id_, expected, given=response.body)
-        finally:
-            fixture.destroy_repo(repo_name)
-
-    def test_api_get_locks_with_one_locked_repo_for_specific_user(self):
-        repo_name = u'api_delete_me'
-        repo = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE,
-                                   cur_user=self.TEST_USER_LOGIN)
-        Repository.lock(repo, User.get_by_username(self.TEST_USER_LOGIN).user_id)
-        try:
-            id_, params = _build_data(self.apikey, 'get_locks',
-                                      userid=self.TEST_USER_LOGIN)
-            response = api_call(self, params)
-            expected = [repo.get_api_data()]
-            self._compare_ok(id_, expected, given=response.body)
-        finally:
-            fixture.destroy_repo(repo_name)
-
-    def test_api_get_locks_with_userid(self):
-        id_, params = _build_data(self.apikey, 'get_locks',
-                                  userid=TEST_USER_REGULAR_LOGIN)
-        response = api_call(self, params)
-        expected = []
-        self._compare_ok(id_, expected, given=response.body)
-
     def test_api_create_existing_user(self):
         id_, params = _build_data(self.apikey, 'create_user',
                                   username=TEST_USER_ADMIN_LOGIN,
@@ -1259,7 +1060,6 @@
         ('clone_uri', {'clone_uri': None}),
         ('landing_rev', {'landing_rev': 'branch:master'}),
         ('enable_statistics', {'enable_statistics': True}),
-        ('enable_locking', {'enable_locking': True}),
         ('enable_downloads', {'enable_downloads': True}),
         ('name', {'name': u'new_repo_name'}),
         ('repo_group', {'group': u'test_group_for_update'}),
@@ -1300,7 +1100,6 @@
         ('clone_uri', {'clone_uri': None}),
         ('landing_rev', {'landing_rev': 'branch:master'}),
         ('enable_statistics', {'enable_statistics': True}),
-        ('enable_locking', {'enable_locking': True}),
         ('enable_downloads', {'enable_downloads': True}),
         ('name', {'name': u'new_repo_name'}),
         ('repo_group', {'group': u'test_group_for_update'}),
--- a/kallithea/tests/fixture.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/tests/fixture.py	Wed Jan 16 02:32:35 2019 +0100
@@ -117,7 +117,6 @@
             parent_group_id=u'-1',
             perms_updates=[],
             perms_new=[],
-            enable_locking=False,
             recursive=False
         )
         defs.update(custom)
--- a/kallithea/tests/functional/test_admin_defaults.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/tests/functional/test_admin_defaults.py	Wed Jan 16 02:32:35 2019 +0100
@@ -10,12 +10,10 @@
         response.mustcontain('default_repo_private')
         response.mustcontain('default_repo_enable_statistics')
         response.mustcontain('default_repo_enable_downloads')
-        response.mustcontain('default_repo_enable_locking')
 
     def test_update_params_true_hg(self):
         self.log_user()
         params = {
-            'default_repo_enable_locking': True,
             'default_repo_enable_downloads': True,
             'default_repo_enable_statistics': True,
             'default_repo_private': True,
@@ -32,7 +30,6 @@
     def test_update_params_false_git(self):
         self.log_user()
         params = {
-            'default_repo_enable_locking': False,
             'default_repo_enable_downloads': False,
             'default_repo_enable_statistics': False,
             'default_repo_private': False,
--- a/kallithea/tests/other/test_vcs_operations.py	Wed May 22 18:06:55 2019 -0400
+++ b/kallithea/tests/other/test_vcs_operations.py	Wed Jan 16 02:32:35 2019 +0100
@@ -176,17 +176,6 @@
         # DISABLE ANONYMOUS ACCESS
         set_anonymous_access(False)
 
-    def setup_method(self, method):
-        r = Repository.get_by_repo_name(GIT_REPO)
-        Repository.unlock(r)
-        r.enable_locking = False
-        Session().commit()
-
-        r = Repository.get_by_repo_name(HG_REPO)
-        Repository.unlock(r)
-        r.enable_locking = False
-        Session().commit()
-
     @pytest.fixture()
     def testhook_cleanup(self):
         yield
@@ -434,157 +423,6 @@
 
         assert 'not found' in stderr
 
-    def test_clone_and_create_lock_hg(self, webserver):
-        # enable locking
-        r = Repository.get_by_repo_name(HG_REPO)
-        r.enable_locking = True
-        Session().commit()
-        # clone
-        clone_url = webserver.repo_url(HG_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, _get_tmp_dir())
-
-        # check if lock was made
-        r = Repository.get_by_repo_name(HG_REPO)
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-    def test_clone_and_create_lock_git(self, webserver):
-        # enable locking
-        r = Repository.get_by_repo_name(GIT_REPO)
-        r.enable_locking = True
-        Session().commit()
-        # clone
-        clone_url = webserver.repo_url(GIT_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, _get_tmp_dir())
-
-        # check if lock was made
-        r = Repository.get_by_repo_name(GIT_REPO)
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-    def test_clone_after_repo_was_locked_hg(self, webserver):
-        # lock repo
-        r = Repository.get_by_repo_name(HG_REPO)
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-        # pull fails since repo is locked
-        clone_url = webserver.repo_url(HG_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True)
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
-        assert msg in stderr
-
-    def test_clone_after_repo_was_locked_git(self, webserver):
-        # lock repo
-        r = Repository.get_by_repo_name(GIT_REPO)
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-        # pull fails since repo is locked
-        clone_url = webserver.repo_url(GIT_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True)
-        msg = ("""The requested URL returned error: 423""")
-        assert msg in stderr
-
-    def test_push_on_locked_repo_by_other_user_hg(self, webserver):
-        # clone some temp
-        dest_dir = _get_tmp_dir()
-        clone_url = webserver.repo_url(HG_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, dest_dir)
-
-        # lock repo
-        r = Repository.get_by_repo_name(HG_REPO)
-        # let this user actually push !
-        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
-                                          perm='repository.write')
-        Session().commit()
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-
-        # push fails repo is locked by other user !
-        stdout, stderr = _add_files_and_push(webserver, 'hg', dest_dir,
-                                             username=TEST_USER_REGULAR_LOGIN,
-                                             password=TEST_USER_REGULAR_PASS,
-                                             ignoreReturnCode=True)
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
-        assert msg in stderr
-
-    def test_push_on_locked_repo_by_other_user_git(self, webserver):
-        # Note: Git hooks must be executable on unix. This test will thus fail
-        # for example on Linux if /tmp is mounted noexec.
-
-        # clone some temp
-        dest_dir = _get_tmp_dir()
-        clone_url = webserver.repo_url(GIT_REPO)
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, dest_dir)
-
-        # lock repo
-        r = Repository.get_by_repo_name(GIT_REPO)
-        # let this user actually push !
-        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
-                                          perm='repository.write')
-        Session().commit()
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-
-        # push fails repo is locked by other user !
-        stdout, stderr = _add_files_and_push(webserver, 'git', dest_dir,
-                                             username=TEST_USER_REGULAR_LOGIN,
-                                             password=TEST_USER_REGULAR_PASS,
-                                             ignoreReturnCode=True)
-        err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
-        assert err in stderr
-
-        # TODO: fix this somehow later on Git, Git is stupid and even if we throw
-        # back 423 to it, it makes ANOTHER request and we fail there with 405 :/
-
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
-        #msg = "405 Method Not Allowed"
-        #assert msg in stderr
-
-    def test_push_unlocks_repository_hg(self, webserver, testfork):
-        # enable locking
-        r = Repository.get_by_repo_name(testfork['hg'])
-        r.enable_locking = True
-        Session().commit()
-        # clone some temp
-        dest_dir = _get_tmp_dir()
-        clone_url = webserver.repo_url(testfork['hg'])
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, dest_dir)
-
-        # check for lock repo after clone
-        r = Repository.get_by_repo_name(testfork['hg'])
-        uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-        assert r.locked[0] == uid
-
-        # push is ok and repo is now unlocked
-        stdout, stderr = _add_files_and_push(webserver, 'hg', dest_dir, clone_url=clone_url)
-        assert str('remote: Released lock on repo `%s`' % testfork['hg']) in stdout
-        # we need to cleanup the Session Here !
-        Session.remove()
-        r = Repository.get_by_repo_name(testfork['hg'])
-        assert r.locked == [None, None]
-
-    # TODO: fix me ! somehow during tests hooks don't get called on Git
-    def test_push_unlocks_repository_git(self, webserver, testfork):
-        # enable locking
-        r = Repository.get_by_repo_name(testfork['git'])
-        r.enable_locking = True
-        Session().commit()
-        # clone some temp
-        dest_dir = _get_tmp_dir()
-        clone_url = webserver.repo_url(testfork['git'])
-        stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, dest_dir)
-
-        # check for lock repo after clone
-        r = Repository.get_by_repo_name(testfork['git'])
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-        # push is ok and repo is now unlocked
-        stdout, stderr = _add_files_and_push(webserver, 'git', dest_dir, clone_url=clone_url)
-        _check_proper_git_push(stdout, stderr)
-
-        assert ('remote: Released lock on repo `%s`' % testfork['git']) in stderr
-        # we need to cleanup the Session Here !
-        Session.remove()
-        r = Repository.get_by_repo_name(testfork['git'])
-        assert r.locked == [None, None]
-
     def test_ip_restriction_hg(self, webserver):
         user_model = UserModel()
         try: