Mercurial > public > mercurial-scm > hg
comparison mercurial/scmutil.py @ 18668:4034b8d551b1
scmutil: create directories in a race-safe way during update
With the new parallel update code, it is possible for multiple
workers to try to create a hierarchy of directories at the same
time. This is hard to trigger in general, but most likely during
initial checkout.
To deal with these races, we introduce a new ensuredirs function
whose contract is to ensure that a directory hierarchy exists - it
will ignore a failure that implies that the desired directory already
exists.
author | Bryan O'Sullivan <bryano@fb.com> |
---|---|
date | Mon, 11 Feb 2013 16:15:12 -0800 |
parents | b114e41c4df3 |
children | 423eee0b0b14 |
comparison
equal
deleted
inserted
replaced
18667:f12804d3ff80 | 18668:4034b8d551b1 |
---|---|
305 # If basename is empty, then the path is malformed because it points | 305 # If basename is empty, then the path is malformed because it points |
306 # to a directory. Let the posixfile() call below raise IOError. | 306 # to a directory. Let the posixfile() call below raise IOError. |
307 if basename: | 307 if basename: |
308 if atomictemp: | 308 if atomictemp: |
309 if not os.path.isdir(dirname): | 309 if not os.path.isdir(dirname): |
310 util.makedirs(dirname, self.createmode) | 310 util.ensuredirs(dirname, self.createmode) |
311 return util.atomictempfile(f, mode, self.createmode) | 311 return util.atomictempfile(f, mode, self.createmode) |
312 try: | 312 try: |
313 if 'w' in mode: | 313 if 'w' in mode: |
314 util.unlink(f) | 314 util.unlink(f) |
315 nlink = 0 | 315 nlink = 0 |
324 except (OSError, IOError), e: | 324 except (OSError, IOError), e: |
325 if e.errno != errno.ENOENT: | 325 if e.errno != errno.ENOENT: |
326 raise | 326 raise |
327 nlink = 0 | 327 nlink = 0 |
328 if not os.path.isdir(dirname): | 328 if not os.path.isdir(dirname): |
329 util.makedirs(dirname, self.createmode) | 329 util.ensuredirs(dirname, self.createmode) |
330 if nlink > 0: | 330 if nlink > 0: |
331 if self._trustnlink is None: | 331 if self._trustnlink is None: |
332 self._trustnlink = nlink > 1 or util.checknlink(f) | 332 self._trustnlink = nlink > 1 or util.checknlink(f) |
333 if nlink > 1 or not self._trustnlink: | 333 if nlink > 1 or not self._trustnlink: |
334 util.rename(util.mktempcopy(f), f) | 334 util.rename(util.mktempcopy(f), f) |
345 except OSError: | 345 except OSError: |
346 pass | 346 pass |
347 | 347 |
348 dirname = os.path.dirname(linkname) | 348 dirname = os.path.dirname(linkname) |
349 if not os.path.exists(dirname): | 349 if not os.path.exists(dirname): |
350 util.makedirs(dirname, self.createmode) | 350 util.ensuredirs(dirname, self.createmode) |
351 | 351 |
352 if self._cansymlink: | 352 if self._cansymlink: |
353 try: | 353 try: |
354 os.symlink(src, linkname) | 354 os.symlink(src, linkname) |
355 except OSError, err: | 355 except OSError, err: |