~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
""")
30
30
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
31
31
                           ReusingTransform, NotVersionedError, CantMoveRoot,
32
 
                           ExistingLimbo, ImmortalLimbo, NoFinalPath)
 
32
                           ExistingLimbo, ImmortalLimbo, NoFinalPath,
 
33
                           UnableCreateSymlink)
33
34
from bzrlib.inventory import InventoryEntry
34
35
from bzrlib.osutils import (file_kind, supports_executable, pathjoin, lexists,
35
 
                            delete_any)
 
36
                            delete_any, has_symlinks)
36
37
from bzrlib.progress import DummyProgress, ProgressPhase
37
38
from bzrlib.symbol_versioning import (
38
39
        deprecated_function,
105
106
    Limbo
106
107
    -----
107
108
    Limbo is a temporary directory use to hold new versions of files.
108
 
    Files are added to limbo by new_file, new_directory, new_symlink, and their
109
 
    convenience variants (create_*).  Files may be removed from limbo using
110
 
    cancel_creation.  Files are renamed from limbo into their final location as
111
 
    part of TreeTransform.apply
 
109
    Files are added to limbo by create_file, create_directory, create_symlink,
 
110
    and their convenience variants (new_*).  Files may be removed from limbo
 
111
    using cancel_creation.  Files are renamed from limbo into their final
 
112
    location as part of TreeTransform.apply
112
113
 
113
114
    Limbo must be cleaned up, by either calling TreeTransform.apply or
114
115
    calling TreeTransform.finalize.
115
116
 
116
117
    Files are placed into limbo inside their parent directories, where
117
118
    possible.  This reduces subsequent renames, and makes operations involving
118
 
    lots of files faster.  This is only possible if the parent directory
119
 
    is created *before* creating any of its children.
 
119
    lots of files faster.  This optimization is only possible if the parent
 
120
    directory is created *before* creating any of its children, so avoid
 
121
    creating children before parents, where possible.
120
122
 
121
123
    Pending-deletion
122
124
    ----------------
123
125
    This temporary directory is used by _FileMover for storing files that are
124
 
    about to be deleted.  FileMover does not delete files until it is
125
 
    sure that a rollback will not happen.  In case of rollback, the files
126
 
    will be restored.
 
126
    about to be deleted.  In case of rollback, the files will be restored.
 
127
    FileMover does not delete files until it is sure that a rollback will not
 
128
    happen.  
127
129
    """
128
130
    def __init__(self, tree, pb=DummyProgress()):
129
131
        """Note: a tree_write lock is taken on the tree.
439
441
        target is a bytestring.
440
442
        See also new_symlink.
441
443
        """
442
 
        os.symlink(target, self._limbo_name(trans_id))
443
 
        unique_add(self._new_contents, trans_id, 'symlink')
 
444
        if has_symlinks():
 
445
            os.symlink(target, self._limbo_name(trans_id))
 
446
            unique_add(self._new_contents, trans_id, 'symlink')
 
447
        else:
 
448
            try:
 
449
                path = FinalPaths(self).get_path(trans_id)
 
450
            except KeyError:
 
451
                path = None
 
452
            raise UnableCreateSymlink(path=path)
444
453
 
445
454
    def cancel_creation(self, trans_id):
446
455
        """Cancel the creation of new file contents."""
1289
1298
            self._known_paths[trans_id] = self._determine_path(trans_id)
1290
1299
        return self._known_paths[trans_id]
1291
1300
 
 
1301
 
1292
1302
def topology_sorted_ids(tree):
1293
1303
    """Determine the topological order of the ids in a tree"""
1294
1304
    file_ids = list(tree)
1320
1330
    finally:
1321
1331
        wt.unlock()
1322
1332
 
 
1333
 
1323
1334
def _build_tree(tree, wt):
1324
1335
    """See build_tree."""
1325
1336
    if len(wt.inventory) > 1:  # more than just a root
1490
1501
    else:
1491
1502
        raise errors.BadFileKindError(name, kind)
1492
1503
 
 
1504
 
1493
1505
def create_by_entry(tt, entry, tree, trans_id, lines=None, mode_id=None):
1494
1506
    """Create new file contents according to an inventory entry."""
1495
1507
    if entry.kind == "file":
1501
1513
    elif entry.kind == "directory":
1502
1514
        tt.create_directory(trans_id)
1503
1515
 
 
1516
 
1504
1517
def create_entry_executability(tt, entry, trans_id):
1505
1518
    """Set the executability of a trans_id according to an inventory entry"""
1506
1519
    if entry.kind == "file":