#!/usr/bin/env python

# ====================================================================
# Copyright (c) 2006 CollabNet.  All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.  The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
# This software consists of voluntary contributions made by many
# individuals.  For exact contribution history, see the revision
# history and logs, available at http://subversion.tigris.org/.
# ====================================================================


"""\
remove-zombie-locks.py - remove zombie locks on deleted files

Usage: remove-zombie-locks.py REPOS-PATH <REVISION|all>

  When REVISION (an interger) is specified this script scans a committed
  revision for deleted files and checks if a lock exists for any of these
  files. If any locks exist they are forcibly removed.

  When "all" is specified this script scans the whole repository for
  locks on files that don't exist in the HEAD revision, removing any found.

  This script is a workaround for Subversion issue #2507
  http://subversion.tigris.org/issues/show_bug.cgi?id=2507

Examples:

  As a post-commit Hook script to prevent zombie locks:
    remove-zombie-locks.py /var/svn/myrepo 6174

  To clean a repository with existing zombie locks:
    remove-zombie-locks.py /var/svn/myrepo all

For additional information read the commented notes in this script.
"""

#
#  ** FAQ **
#
#  What is the problem, exactly?
#
#  When you commit a file deletion with the --keep-locks option then
#  though the file is deleted in the repository, the lock is not.
#  This is a bug in Subversion.  If locks are left on deleted files
#  then any future attempt to add a file of the same name or
#  delete/move/rename any parent directory will fail.  This is very
#  difficult for the end-user to fix since there's no easy way to find
#  out the names of these zombie locks, and it is not simple to remove
#  them even if you do know the names.
#
#  Is this script 100% safe?
#
#  There is a theoretical and very small chance that before this
#  script runs another commit adds a file with the same path as one
#  just deleted in this revision, and then a lock is acquired for it,
#  resulting in this script unlocking the "wrong" file. In practice it
#  seems highly improbable and would require very strange performance
#  characteristics on your svn server.  However, to minimize the
#  window for error it is recommended to run this script first in your
#  post-commit hook.
#
#  How Do I Start Using This Script?
#
#  1. Once only, run this script in 'all' mode to start your repo out clean
#  2. Call this script from your post-commit hook to keep your repo clean
#

import os
import sys

import svn.core
import svn.repos
import svn.fs

assert (svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR) >= (1, 2), \
       "Subversion 1.2 or later required but only have " \
       + str(svn.core.SVN_VER_MAJOR) + "." + str(svn.core.SVN_VER_MINOR)

def usage_and_exit():
  print >> sys.stderr, __doc__
  sys.exit(1)

class RepositoryZombieLockRemover:
  """Remove all locks on non-existent files in repository@HEAD"""
  def __init__(self, repos_path, repos_subpath=""):
    self.repos_path = repos_path  # path to repository on disk
    self.repos_subpath = repos_subpath  # if only cleaning part of the repo

    # init svn
    svn.core.apr_initialize()
    self.pool = svn.core.svn_pool_create(None)
    self.repos_ptr = svn.repos.open(self.repos_path, self.pool)
    self.fs_ptr = svn.repos.fs(self.repos_ptr)
    self.fs_type = svn.fs.type(svn.repos.db_env(self.repos_ptr))
    self.rev_root = svn.fs.revision_root(self.fs_ptr,
                                         svn.fs.youngest_rev(self.fs_ptr,
                                                             self.pool),
                                         self.pool)

  def __del__(self):
    svn.core.svn_pool_destroy(self.pool)
    svn.core.apr_terminate()

  def unlock_nonexistent_files(self, lock, callback_pool):
    """check if the file still exists in HEAD, removing the lock if not"""
    if svn.fs.svn_fs_check_path(self.rev_root, lock.path, callback_pool) \
           == svn.core.svn_node_none:
      print lock.path
      svn.repos.svn_repos_fs_unlock(self.repos_ptr, lock.path, lock.token,
                                    True, callback_pool)

  def run(self):
    """iterate over every locked file in repo_path/repo_subpath,
       calling unlock_nonexistent_files for each"""

    print "Removing all zombie locks from repository at %s\n" \
          "This may take several minutes..." % self.repos_path

    # Try to use svn_fs_get_locks2() if it's present, as it's believed
    # to be problem-free.
    #
    # If not, use svn_fs_get_locks().  But note that Subversion's
    # Berkeley DB implementation of svn_fs_get_locks() in 1.6 and
    # prior doesn't allow reentry of its BDB-transaction-using APIs
    # from within BDB-transaction-using APIs (such as
    # svn_fs_get_locks()).  So we have do this in two steps, first
    # harvest the locks, then checking/removing them.
    if hasattr(svn.fs, 'svn_fs_get_locks2'):
      svn.fs.svn_fs_get_locks2(self.fs_ptr, self.repos_subpath,
                               svn.core.svn_depth_infinity,
                               self.unlock_nonexistent_files, self.pool)
    else:
      if self.fs_type == svn.fs.SVN_FS_TYPE_BDB:
        self.locks = []
        def bdb_lock_callback(lock, callback_pool):
          self.locks.append(lock)
        svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
                                bdb_lock_callback, self.pool)
        subpool = svn.core.svn_pool_create(self.pool)
        for lock in self.locks:
          svn.core.svn_pool_clear(subpool)
          self.unlock_nonexistent_files(lock, subpool)
        svn.core.svn_pool_destroy(subpool)
      else:
        svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
                                self.unlock_nonexistent_files, self.pool)
    print "Done."


class RevisionZombieLockRemover:
  """Remove all locks on files deleted in a revision"""
  def __init__(self, repos_path, repos_rev):
    self.repos_path = repos_path  # path to repository on disk

    # init svn
    svn.core.apr_initialize()
    self.pool = svn.core.svn_pool_create(None)
    self.repos_ptr = svn.repos.open(self.repos_path, self.pool)
    self.fs_ptr = svn.repos.fs(self.repos_ptr)
    self.rev_root = svn.fs.revision_root(self.fs_ptr, repos_rev, self.pool)

  def __del__(self):
    svn.core.svn_pool_destroy(self.pool)
    svn.core.apr_terminate()

  def get_deleted_paths(self):
    """return list of deleted paths in a revision"""
    deleted_paths = []
    for path, change in \
        svn.fs.paths_changed(self.rev_root, self.pool).iteritems():
      if (change.change_kind == svn.fs.path_change_delete):
        deleted_paths.append(path)
    return deleted_paths

  def run(self):
    """remove any existing locks on files that are deleted in this revision"""
    deleted_paths = self.get_deleted_paths()
    subpool = svn.core.svn_pool_create(self.pool)
    for path in deleted_paths:
      svn.core.svn_pool_clear(subpool)
      lock = svn.fs.svn_fs_get_lock(self.fs_ptr, path, subpool)
      if lock:
        svn.repos.svn_repos_fs_unlock(self.repos_ptr, path,
                                      lock.token, True, subpool)
    svn.core.svn_pool_destroy(subpool)


def main():
  if len(sys.argv) < 3:
    usage_and_exit()
  repos_path = os.path.abspath(sys.argv[1])
  if sys.argv[2].lower() == "all":
    remover = RepositoryZombieLockRemover(repos_path, "")
  else:
    try:
      repos_rev = int(sys.argv[2])
    except ValueError:
      usage_and_exit()
    remover = RevisionZombieLockRemover(repos_path, repos_rev)

  remover.run()

  sys.exit(0)


if __name__ == "__main__":
  main()

