/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« 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:
354
354
        if typefunc(mode):
355
355
            os.chmod(self._limbo_name(trans_id), mode)
356
356
 
 
357
    def create_hardlink(self, path, trans_id):
 
358
        """Schedule creation of a hard link"""
 
359
        name = self._limbo_name(trans_id)
 
360
        try:
 
361
            os.link(path, name)
 
362
        except OSError, e:
 
363
            if e.errno != errno.EPERM:
 
364
                raise
 
365
            raise errors.HardLinkNotSupported(path)
 
366
        try:
 
367
            unique_add(self._new_contents, trans_id, 'file')
 
368
        except:
 
369
            # Clean up the file, it never got registered so
 
370
            # TreeTransform.finalize() won't clean it up.
 
371
            os.unlink(name)
 
372
            raise
 
373
 
357
374
    def create_directory(self, trans_id):
358
375
        """Schedule creation of a new directory.
359
376
        
1407
1424
        name = self._transform._limbo_name(trans_id)
1408
1425
        return open(name, 'rb')
1409
1426
 
 
1427
    def get_symlink_target(self, file_id):
 
1428
        """See Tree.get_symlink_target"""
 
1429
        trans_id = self._transform.trans_id_file_id(file_id)
 
1430
        name = self._transform._limbo_name(trans_id)
 
1431
        return os.readlink(name)
 
1432
 
1410
1433
    def paths2ids(self, specific_files, trees=None, require_versioned=False):
1411
1434
        """See Tree.paths2ids"""
1412
1435
        return 'not_empty'
1455
1478
    return file_ids
1456
1479
 
1457
1480
 
1458
 
def build_tree(tree, wt, accelerator_tree=None):
 
1481
def build_tree(tree, wt, accelerator_tree=None, hardlink=False):
1459
1482
    """Create working tree for a branch, using a TreeTransform.
1460
1483
    
1461
1484
    This function should be used on empty trees, having a tree root at most.
1474
1497
    :param accelerator_tree: A tree which can be used for retrieving file
1475
1498
        contents more quickly than tree itself, i.e. a workingtree.  tree
1476
1499
        will be used for cases where accelerator_tree's content is different.
 
1500
    :param hardlink: If true, hard-link files to accelerator_tree, where
 
1501
        possible.  accelerator_tree must implement abspath, i.e. be a
 
1502
        working tree.
1477
1503
    """
1478
1504
    wt.lock_tree_write()
1479
1505
    try:
1482
1508
            if accelerator_tree is not None:
1483
1509
                accelerator_tree.lock_read()
1484
1510
            try:
1485
 
                return _build_tree(tree, wt, accelerator_tree)
 
1511
                return _build_tree(tree, wt, accelerator_tree, hardlink)
1486
1512
            finally:
1487
1513
                if accelerator_tree is not None:
1488
1514
                    accelerator_tree.unlock()
1492
1518
        wt.unlock()
1493
1519
 
1494
1520
 
1495
 
def _build_tree(tree, wt, accelerator_tree):
 
1521
def _build_tree(tree, wt, accelerator_tree, hardlink):
1496
1522
    """See build_tree."""
1497
1523
    if len(wt.inventory) > 1:  # more than just a root
1498
1524
        raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
1519
1545
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
1520
1546
        try:
1521
1547
            deferred_contents = []
 
1548
            num = 0
1522
1549
            for num, (tree_path, entry) in \
1523
1550
                enumerate(tree.inventory.iter_entries_by_dir()):
1524
1551
                pb.update("Building tree", num - len(deferred_contents),
1568
1595
                    new_trans_id = file_trans_id[file_id]
1569
1596
                    old_parent = tt.trans_id_tree_path(tree_path)
1570
1597
                    _reparent_children(tt, old_parent, new_trans_id)
1571
 
            for num, (trans_id, bytes) in enumerate(
1572
 
                _iter_files_bytes_accelerated(tree, accelerator_tree,
1573
 
                                              deferred_contents)):
1574
 
                tt.create_file(bytes, trans_id)
1575
 
                pb.update('Adding file contents',
1576
 
                          (num + len(tree.inventory) - len(deferred_contents)),
1577
 
                          len(tree.inventory))
 
1598
            offset = num + 1 - len(deferred_contents)
 
1599
            _create_files(tt, tree, deferred_contents, pb, offset,
 
1600
                          accelerator_tree, hardlink)
1578
1601
        finally:
1579
1602
            pb.finished()
1580
1603
        pp.next_phase()
1595
1618
    return result
1596
1619
 
1597
1620
 
1598
 
def _iter_files_bytes_accelerated(tree, accelerator_tree, desired_files):
 
1621
def _create_files(tt, tree, desired_files, pb, offset, accelerator_tree,
 
1622
                  hardlink):
 
1623
    total = len(desired_files) + offset
1599
1624
    if accelerator_tree is None:
1600
1625
        new_desired_files = desired_files
1601
1626
    else:
1602
1627
        iter = accelerator_tree._iter_changes(tree, include_unchanged=True)
1603
1628
        unchanged = dict((f, p[1]) for (f, p, c, v, d, n, k, e)
1604
 
                         in iter if not c)
 
1629
                         in iter if not (c or e[0] != e[1]))
1605
1630
        new_desired_files = []
1606
 
        for file_id, identifier in desired_files:
 
1631
        count = 0
 
1632
        for file_id, trans_id in desired_files:
1607
1633
            accelerator_path = unchanged.get(file_id)
1608
1634
            if accelerator_path is None:
1609
 
                new_desired_files.append((file_id, identifier))
 
1635
                new_desired_files.append((file_id, trans_id))
1610
1636
                continue
1611
 
            contents = accelerator_tree.get_file(file_id, accelerator_path)
1612
 
            try:
1613
 
                want_new = False
1614
 
                contents_bytes = (contents.read(),)
1615
 
            finally:
1616
 
                contents.close()
1617
 
            yield identifier, contents_bytes
1618
 
    for result in tree.iter_files_bytes(new_desired_files):
1619
 
        yield result
 
1637
            pb.update('Adding file contents', count + offset, total)
 
1638
            if hardlink:
 
1639
                tt.create_hardlink(accelerator_tree.abspath(accelerator_path),
 
1640
                                   trans_id)
 
1641
            else:
 
1642
                contents = accelerator_tree.get_file(file_id, accelerator_path)
 
1643
                try:
 
1644
                    tt.create_file(contents, trans_id)
 
1645
                finally:
 
1646
                    contents.close()
 
1647
            count += 1
 
1648
        offset += count
 
1649
    for count, (trans_id, contents) in enumerate(tree.iter_files_bytes(
 
1650
                                                 new_desired_files)):
 
1651
        tt.create_file(contents, trans_id)
 
1652
        pb.update('Adding file contents', count + offset, total)
1620
1653
 
1621
1654
 
1622
1655
def _reparent_children(tt, old_parent, new_parent):