Skip to content

Commit 38b5c38

Browse files
authored
Merge pull request #115 from DEKHTIARJonathan/patch-1
Potential Race Condition Fix - OS Rename & Chmod - PermissionError
2 parents a8c894f + b71e273 commit 38b5c38

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

Diff for: gitdb/db/loose.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import tempfile
5555
import os
5656
import sys
57+
import time
5758

5859

5960
__all__ = ('LooseObjectDB', )
@@ -205,7 +206,7 @@ def store(self, istream):
205206
# END assure target stream is closed
206207
except:
207208
if tmp_path:
208-
os.remove(tmp_path)
209+
remove(tmp_path)
209210
raise
210211
# END assure tmpfile removal on error
211212

@@ -228,9 +229,22 @@ def store(self, istream):
228229
rename(tmp_path, obj_path)
229230
# end rename only if needed
230231

231-
# make sure its readable for all ! It started out as rw-- tmp file
232-
# but needs to be rwrr
233-
chmod(obj_path, self.new_objects_mode)
232+
# Ensure rename is actually done and file is stable
233+
# Retry up to 14 times - exponential wait & retry in ms.
234+
# The total maximum wait time is 1000ms, which should be vastly enough for the
235+
# OS to return and commit the file to disk.
236+
for exp_backoff_ms in [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 181]:
237+
with suppress(PermissionError):
238+
# make sure its readable for all ! It started out as rw-- tmp file
239+
# but needs to be rwrr
240+
chmod(obj_path, self.new_objects_mode)
241+
break
242+
time.sleep(exp_backoff_ms / 1000.0)
243+
else:
244+
raise PermissionError(
245+
"Impossible to apply `chmod` to file {}".format(obj_path)
246+
)
247+
234248
# END handle dry_run
235249

236250
istream.binsha = hex_to_bin(hexsha)

0 commit comments

Comments
 (0)