~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Martin Pool
  • Date: 2010-04-01 04:41:18 UTC
  • mto: This revision was merged to the branch mainline in revision 5128.
  • Revision ID: mbp@sourcefrog.net-20100401044118-shyctqc02ob08ngz
ignore .testrepository

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
    annotate,
26
26
    bencode,
27
27
    bzrdir,
28
 
    commit,
29
28
    delta,
30
29
    errors,
31
30
    inventory,
36
35
    )
37
36
""")
38
37
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
39
 
                           ReusingTransform, CantMoveRoot,
 
38
                           ReusingTransform, NotVersionedError, CantMoveRoot,
40
39
                           ExistingLimbo, ImmortalLimbo, NoFinalPath,
41
40
                           UnableCreateSymlink)
42
41
from bzrlib.filters import filtered_output_bytes, ContentFilterContext
928
927
        """
929
928
        return _PreviewTree(self)
930
929
 
931
 
    def commit(self, branch, message, merge_parents=None, strict=False,
932
 
               timestamp=None, timezone=None, committer=None, authors=None,
933
 
               revprops=None, revision_id=None):
 
930
    def commit(self, branch, message, merge_parents=None, strict=False):
934
931
        """Commit the result of this TreeTransform to a branch.
935
932
 
936
933
        :param branch: The branch to commit to.
937
934
        :param message: The message to attach to the commit.
938
 
        :param merge_parents: Additional parent revision-ids specified by
939
 
            pending merges.
940
 
        :param strict: If True, abort the commit if there are unversioned
941
 
            files.
942
 
        :param timestamp: if not None, seconds-since-epoch for the time and
943
 
            date.  (May be a float.)
944
 
        :param timezone: Optional timezone for timestamp, as an offset in
945
 
            seconds.
946
 
        :param committer: Optional committer in email-id format.
947
 
            (e.g. "J Random Hacker <jrandom@example.com>")
948
 
        :param authors: Optional list of authors in email-id format.
949
 
        :param revprops: Optional dictionary of revision properties.
950
 
        :param revision_id: Optional revision id.  (Specifying a revision-id
951
 
            may reduce performance for some non-native formats.)
 
935
        :param merge_parents: Additional parents specified by pending merges.
952
936
        :return: The revision_id of the revision committed.
953
937
        """
954
938
        self._check_malformed()
971
955
        if self._tree.get_revision_id() != last_rev_id:
972
956
            raise ValueError('TreeTransform not based on branch basis: %s' %
973
957
                             self._tree.get_revision_id())
974
 
        revprops = commit.Commit.update_revprops(revprops, branch, authors)
975
 
        builder = branch.get_commit_builder(parent_ids,
976
 
                                            timestamp=timestamp,
977
 
                                            timezone=timezone,
978
 
                                            committer=committer,
979
 
                                            revprops=revprops,
980
 
                                            revision_id=revision_id)
 
958
        builder = branch.get_commit_builder(parent_ids)
981
959
        preview = self.get_preview_tree()
982
960
        list(builder.record_iter_changes(preview, last_rev_id,
983
961
                                         self.iter_changes()))
1657
1635
                      or trans_id in self._new_parent):
1658
1636
                    try:
1659
1637
                        mover.rename(full_path, self._limbo_name(trans_id))
1660
 
                    except errors.TransformRenameFailed, e:
 
1638
                    except OSError, e:
1661
1639
                        if e.errno != errno.ENOENT:
1662
1640
                            raise
1663
1641
                    else:
1688
1666
                if trans_id in self._needs_rename:
1689
1667
                    try:
1690
1668
                        mover.rename(self._limbo_name(trans_id), full_path)
1691
 
                    except errors.TransformRenameFailed, e:
 
1669
                    except OSError, e:
1692
1670
                        # We may be renaming a dangling inventory id
1693
1671
                        if e.errno != errno.ENOENT:
1694
1672
                            raise
1792
1770
        parent_keys = [(file_id, self._file_revision(t, file_id)) for t in
1793
1771
                       self._iter_parent_trees()]
1794
1772
        vf.add_lines((file_id, tree_revision), parent_keys,
1795
 
                     self.get_file_lines(file_id))
 
1773
                     self.get_file(file_id).readlines())
1796
1774
        repo = self._get_repository()
1797
1775
        base_vf = repo.texts
1798
1776
        if base_vf not in vf.fallback_versionedfiles:
1820
1798
            executable = self.is_executable(file_id, path)
1821
1799
        return kind, executable, None
1822
1800
 
1823
 
    def is_locked(self):
1824
 
        return False
1825
 
 
1826
1801
    def lock_read(self):
1827
1802
        # Perhaps in theory, this should lock the TreeTransform?
1828
 
        return self
 
1803
        pass
1829
1804
 
1830
1805
    def unlock(self):
1831
1806
        pass
2291
2266
    for num, _unused in enumerate(wt.all_file_ids()):
2292
2267
        if num > 0:  # more than just a root
2293
2268
            raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
 
2269
    existing_files = set()
 
2270
    for dir, files in wt.walkdirs():
 
2271
        existing_files.update(f[0] for f in files)
2294
2272
    file_trans_id = {}
2295
2273
    top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
2296
2274
    pp = ProgressPhase("Build phase", 2, top_pb)
2320
2298
                precomputed_delta = []
2321
2299
            else:
2322
2300
                precomputed_delta = None
2323
 
            # Check if tree inventory has content. If so, we populate
2324
 
            # existing_files with the directory content. If there are no
2325
 
            # entries we skip populating existing_files as its not used.
2326
 
            # This improves performance and unncessary work on large
2327
 
            # directory trees. (#501307)
2328
 
            if total > 0:
2329
 
                existing_files = set()
2330
 
                for dir, files in wt.walkdirs():
2331
 
                    existing_files.update(f[0] for f in files)
2332
2301
            for num, (tree_path, entry) in \
2333
2302
                enumerate(tree.inventory.iter_entries_by_dir()):
2334
2303
                pb.update("Building tree", num - len(deferred_contents), total)
2466
2435
    if entry.kind == "directory":
2467
2436
        return True
2468
2437
    if entry.kind == "file":
2469
 
        f = file(target_path, 'rb')
2470
 
        try:
2471
 
            if tree.get_file_text(file_id) == f.read():
2472
 
                return True
2473
 
        finally:
2474
 
            f.close()
 
2438
        if tree.get_file(file_id).read() == file(target_path, 'rb').read():
 
2439
            return True
2475
2440
    elif entry.kind == "symlink":
2476
2441
        if tree.get_symlink_target(file_id) == os.readlink(target_path):
2477
2442
            return True
2529
2494
        raise errors.BadFileKindError(name, kind)
2530
2495
 
2531
2496
 
 
2497
@deprecated_function(deprecated_in((1, 9, 0)))
 
2498
def create_by_entry(tt, entry, tree, trans_id, lines=None, mode_id=None):
 
2499
    """Create new file contents according to an inventory entry.
 
2500
 
 
2501
    DEPRECATED.  Use create_from_tree instead.
 
2502
    """
 
2503
    if entry.kind == "file":
 
2504
        if lines is None:
 
2505
            lines = tree.get_file(entry.file_id).readlines()
 
2506
        tt.create_file(lines, trans_id, mode_id=mode_id)
 
2507
    elif entry.kind == "symlink":
 
2508
        tt.create_symlink(tree.get_symlink_target(entry.file_id), trans_id)
 
2509
    elif entry.kind == "directory":
 
2510
        tt.create_directory(trans_id)
 
2511
 
 
2512
 
2532
2513
def create_from_tree(tt, trans_id, tree, file_id, bytes=None,
2533
2514
    filter_tree_path=None):
2534
2515
    """Create new file contents according to tree contents.
2843
2824
                        # special-case the other tree root (move its
2844
2825
                        # children to current root)
2845
2826
                        if entry.parent_id is None:
2846
 
                            create = False
 
2827
                            create=False
2847
2828
                            moved = _reparent_transform_children(
2848
2829
                                tt, trans_id, tt.root)
2849
2830
                            for child in moved:
2917
2898
        self.pending_deletions = []
2918
2899
 
2919
2900
    def rename(self, from_, to):
2920
 
        """Rename a file from one path to another."""
 
2901
        """Rename a file from one path to another.  Functions like os.rename"""
2921
2902
        try:
2922
2903
            os.rename(from_, to)
2923
2904
        except OSError, e:
2924
2905
            if e.errno in (errno.EEXIST, errno.ENOTEMPTY):
2925
2906
                raise errors.FileExists(to, str(e))
2926
 
            # normal OSError doesn't include filenames so it's hard to see where
2927
 
            # the problem is, see https://bugs.launchpad.net/bzr/+bug/491763
2928
 
            raise errors.TransformRenameFailed(from_, to, str(e), e.errno)
 
2907
            raise
2929
2908
        self.past_renames.append((from_, to))
2930
2909
 
2931
2910
    def pre_delete(self, from_, to):
2941
2920
    def rollback(self):
2942
2921
        """Reverse all renames that have been performed"""
2943
2922
        for from_, to in reversed(self.past_renames):
2944
 
            try:
2945
 
                os.rename(to, from_)
2946
 
            except OSError, e:
2947
 
                raise errors.TransformRenameFailed(to, from_, str(e), e.errno)                
 
2923
            os.rename(to, from_)
2948
2924
        # after rollback, don't reuse _FileMover
2949
2925
        past_renames = None
2950
2926
        pending_deletions = None