Dulwich.io dulwich / 5a446a7
Use os.sync where possible. Check st_size to prevent reading existing file unless it has the same size as the old file in build_file_from_blob. Jelmer Vernooń≥ 2 years ago
2 changed file(s) with 25 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
421421 :param honor_filemode: An optional flag to honor core.filemode setting in
422422 config file, default is core.filemode=True, change executable bit
423423 """
424 try:
425 oldstat = os.stat(target_path)
426 except OSError as e:
427 if e.errno == errno.ENOENT:
428 oldstat = None
429 else:
430 raise
431 contents = blob.as_raw_string()
424432 if stat.S_ISLNK(mode):
425433 # FIXME: This will fail on Windows. What should we do instead?
426 src_path = blob.as_raw_string()
427 try:
428 os.symlink(src_path, target_path)
429 except OSError as e:
430 if e.errno == errno.EEXIST:
431 os.unlink(target_path)
432 os.symlink(src_path, target_path)
433 else:
434 raise
434 if oldstat:
435 os.unlink(target_path)
436 os.symlink(contents, target_path)
435437 else:
436 if os.path.exists(target_path):
438 if oldstat is not None and oldstat.st_size == len(contents):
437439 with open(target_path, 'rb') as f:
438 if f.read() == blob.as_raw_string():
440 if f.read() == contents:
439441 return
440442
441443 with open(target_path, 'wb') as f:
442444 # Write out file
443 f.write(blob.as_raw_string())
445 f.write(contents)
444446
445447 if honor_filemode:
446448 os.chmod(target_path, mode)
368368 sorted(os.listdir(os.path.join(repo.path, 'c'))))
369369
370370 def test_norewrite(self):
371 repo_dir = tempfile.mkdtemp()
372 self.addCleanup(shutil.rmtree, repo_dir)
373 with Repo.init(repo_dir) as repo:
374
371 sync = getattr(os, 'sync', lambda: os.system('sync'))
372 repo_dir = tempfile.mkdtemp()
373 self.addCleanup(shutil.rmtree, repo_dir)
374 with Repo.init(repo_dir) as repo:
375375 # Populate repo
376376 filea = Blob.from_string(b'file a')
377377 filea_path = os.path.join(repo_dir, 'a')
385385 build_index_from_tree(repo.path, repo.index_path(),
386386 repo.object_store, tree.id)
387387 # Use sync as metadata can be cached on some FS
388 os.system('sync')
388 sync()
389389 mtime = os.stat(filea_path).st_mtime
390390
391391 # Test Rewrite
392392 build_index_from_tree(repo.path, repo.index_path(),
393393 repo.object_store, tree.id)
394 os.system('sync')
395 self.assertEqual(mtime,
396 os.stat(filea_path).st_mtime)
394 sync()
395 self.assertEqual(mtime, os.stat(filea_path).st_mtime)
397396
398397 # Modify content
399398 with open(filea_path, 'wb') as fh:
400399 fh.write(b'test a')
401 os.system('sync')
400 sync()
402401 mtime = os.stat(filea_path).st_mtime
403
402
404403 # Test rewrite
405404 build_index_from_tree(repo.path, repo.index_path(),
406405 repo.object_store, tree.id)
407 os.system('sync')
408 self.assertNotEqual(mtime,
409 os.stat(filea_path).st_mtime)
406 sync()
407 self.assertNotEqual(mtime, os.stat(filea_path).st_mtime)
410408
411409
412410 @skipIf(not getattr(os, 'symlink', None), 'Requires symlink support')