Advertisement
mechanicker

git repository locking

Jan 28th, 2025 (edited)
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.56 KB | None | 0 0
  1. import os
  2. from interruptingcow import timeout as interruptingcow_timeout
  3.  
  4. class MigrationAbortException(Exception):
  5.     """Exception raised when a migration is aborted."""
  6.     pass
  7.  
  8. def lock_repository_ref_updates(repo_path: bytes):
  9.     """git never updates refs or packed-refs file in-place. It always writes into a
  10.    new temporary file and renames. Making the parent directory read-only is sufficient
  11.    to prevent creating temporary file or renaming the file since there are directory updates"""
  12.     migration_abort_sentinel = os.path.join(repo_path, b'migration-abort-sentinel')
  13.     refs_dir = os.path.join(repo_path, b'refs')
  14.  
  15.     def make_dir_read_only(path: bytes):
  16.         # Even if we are in uninterruptible state, SIGALRM will eventually
  17.         # get delivered to the process. Once delivered, will raise exception
  18.         with interruptingcow_timeout(seconds=60, exception=MigrationAbortException):
  19.             try:
  20.                 os.chmod(path, 0o500)
  21.             except FileNotFoundError:
  22.                 pass
  23.             except Exception as ex:
  24.                 raise MigrationAbortException(ex)
  25.  
  26.             # Check if rollback is initiated and bailout
  27.             if os.access(migration_abort_sentinel, os.R_OK):
  28.                 raise MigrationAbortException()
  29.  
  30.     # Lock top-down and this will ensure the level
  31.     # we are iterating will not change beneath us
  32.     make_dir_read_only(refs_dir)
  33.     for root, dirs, _ in os.walk(top=refs_dir, topdown=False):
  34.         for name in dirs:
  35.             make_dir_read_only(path=os.path.join(root, name))
  36.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement