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: