Mercurial > hg
comparison mercurial/util.py @ 8256:e68e149f4d44
Merge with crew-stable
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Wed, 29 Apr 2009 23:56:20 +0200 |
parents | 0a9542703300 ea82a23cf887 |
children | e745063b94dd |
comparison
equal
deleted
inserted
replaced
8254:f108e89400d8 | 8256:e68e149f4d44 |
---|---|
628 def rename(src, dst): | 628 def rename(src, dst): |
629 """forcibly rename a file""" | 629 """forcibly rename a file""" |
630 try: | 630 try: |
631 os.rename(src, dst) | 631 os.rename(src, dst) |
632 except OSError, err: # FIXME: check err (EEXIST ?) | 632 except OSError, err: # FIXME: check err (EEXIST ?) |
633 # on windows, rename to existing file is not allowed, so we | 633 |
634 # must delete destination first. but if file is open, unlink | 634 # On windows, rename to existing file is not allowed, so we |
635 # schedules it for delete but does not delete it. rename | 635 # must delete destination first. But if a file is open, unlink |
636 # schedules it for delete but does not delete it. Rename | |
636 # happens immediately even for open files, so we rename | 637 # happens immediately even for open files, so we rename |
637 # destination to a temporary name, then delete that. then | 638 # destination to a temporary name, then delete that. Then |
638 # rename is safe to do. | 639 # rename is safe to do. |
639 temp = dst + "-force-rename" | 640 # The temporary name is chosen at random to avoid the situation |
641 # where a file is left lying around from a previous aborted run. | |
642 # The usual race condition this introduces can't be avoided as | |
643 # we need the name to rename into, and not the file itself. Due | |
644 # to the nature of the operation however, any races will at worst | |
645 # lead to the rename failing and the current operation aborting. | |
646 | |
647 def tempname(prefix): | |
648 for tries in xrange(10): | |
649 temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) | |
650 if not os.path.exists(temp): | |
651 return temp | |
652 raise IOError, (errno.EEXIST, "No usable temporary filename found") | |
653 | |
654 temp = tempname(dst) | |
640 os.rename(dst, temp) | 655 os.rename(dst, temp) |
641 os.unlink(temp) | 656 os.unlink(temp) |
642 os.rename(src, dst) | 657 os.rename(src, dst) |
643 | 658 |
644 def unlink(f): | 659 def unlink(f): |