summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/git/index.py34
1 files changed, 33 insertions, 1 deletions
diff --git a/lib/git/index.py b/lib/git/index.py
index 991c77da..041dfff7 100644
--- a/lib/git/index.py
+++ b/lib/git/index.py
@@ -21,7 +21,7 @@ import git.diff as diff
from errors import GitCommandError
from git.objects import Blob, Tree, Object, Commit
-from git.utils import SHA1Writer, LazyMixin, ConcurrentWriteOperation, join_path_native
+from git.utils import SHA1Writer, LazyMixin, ConcurrentWriteOperation, join_path_native, BlockingLockFile
class CheckoutError( Exception ):
@@ -70,6 +70,38 @@ class _TemporaryFileSwap(object):
os.rename(self.tmp_file_path, self.file_path)
# END temp file exists
+class IndexLock(BlockingLockFile):
+ """Specialized lock that will wait for the index to be locked and immediately
+ move the lock out of the way. This allows a git command to take the lock
+ which has to follow right after the lock() call.
+
+ Right before the lock is released, we will move our original lock back into place.
+ This lock should be used to gain fine-grained control over multiple processes
+ or threads that try to manipulate the index and would otherwise fail.
+ Using this lock, these will wait for each other.
+
+ NOTE:
+ There is still a small chance that git will fail as file system
+ operations take time as well.
+ """
+ __slots__ = '_tmp_file_path'
+
+ def _obtain_lock_or_raise(self):
+ super(IndexLock, self)._obtain_lock_or_raise()
+ self._tmp_file_path = self._lock_file_path() + tempfile.mktemp('','','')
+ # rename lock we aquired to move it out of the way
+ os.rename(self._lock_file_path(), self._tmp_file_path)
+
+ def _release_lock(self):
+ # move our lock back into place
+ if hasattr(self, '_tmp_file_path') and os.path.isfile(self._tmp_file_path):
+ lock_file = self._lock_file_path()
+ if os.name == 'nt' and os.path.exists(lock_file):
+ os.remove(lock_file)
+ os.rename(self._tmp_file_path, lock_file)
+ # END temp file exists
+ super(IndexLock, self)._release_lock()
+
class BlobFilter(object):
"""
Predicate to be used by iter_blobs allowing to filter only return blobs which