Skip to content

Commit d6b1a92

Browse files
committed
fix(index): improve LockedFD handling
Relying on the destructor will not work, even though the code used to rely on it. Now we handle failures more explicitly. Far from perfect, but a good start for a fix. Fixes gitpython-developers#514
1 parent 2d37049 commit d6b1a92

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

git/index/base.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,17 @@ def _set_cache_(self, attr):
118118
# read the current index
119119
# try memory map for speed
120120
lfd = LockedFD(self._file_path)
121+
ok = False
121122
try:
122123
fd = lfd.open(write=False, stream=False)
124+
ok = True
123125
except OSError:
124-
lfd.rollback()
125126
# in new repositories, there may be no index, which means we are empty
126127
self.entries = dict()
127128
return
129+
finally:
130+
if not ok:
131+
lfd.rollback()
128132
# END exception handling
129133

130134
# Here it comes: on windows in python 2.5, memory maps aren't closed properly
@@ -209,8 +213,14 @@ def write(self, file_path=None, ignore_extension_data=False):
209213
self.entries
210214
lfd = LockedFD(file_path or self._file_path)
211215
stream = lfd.open(write=True, stream=True)
216+
ok = False
212217

213-
self._serialize(stream, ignore_extension_data)
218+
try:
219+
self._serialize(stream, ignore_extension_data)
220+
ok = True
221+
finally:
222+
if not ok:
223+
lfd.rollback()
214224

215225
lfd.commit()
216226

git/test/test_index.py

+17
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,23 @@ def _cmp_tree_index(self, tree, index):
135135
raise AssertionError("CMP Failed: Missing entries in index: %s, missing in tree: %s" %
136136
(bset - iset, iset - bset))
137137
# END assertion message
138+
139+
@with_rw_repo('0.1.6')
140+
def test_index_lock_handling(self, rw_repo):
141+
def add_bad_blob():
142+
rw_repo.index.add([Blob(rw_repo, b'f' * 20, 'bad-permissions', 'foo')])
143+
144+
try:
145+
## 1st fail on purpose adding into index.
146+
add_bad_blob()
147+
except Exception as ex:
148+
assert "cannot convert argument to integer" in str(ex)
149+
150+
## 2nd time should not fail due to stray lock file
151+
try:
152+
add_bad_blob()
153+
except Exception as ex:
154+
assert "index.lock' could not be obtained" not in str(ex)
138155

139156
@with_rw_repo('0.1.6')
140157
def test_index_file_from_tree(self, rw_repo):

0 commit comments

Comments
 (0)