~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: John Arbash Meinel
  • Date: 2007-07-11 23:45:20 UTC
  • mfrom: (2601 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2643.
  • Revision ID: john@arbash-meinel.com-20070711234520-do3h7zw8skbathpz
[merge] bzr.dev 2601

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
lazy_import(globals(), """
45
45
from bisect import bisect_left
46
46
import collections
47
 
from copy import deepcopy
48
47
import errno
49
48
import itertools
50
49
import operator
616
615
        # should probably put it back with the previous ID.
617
616
        # the read and write working inventory should not occur in this 
618
617
        # function - they should be part of lock_write and unlock.
619
 
        inv = self.read_working_inventory()
 
618
        inv = self.inventory
620
619
        for f, file_id, kind in zip(files, ids, kinds):
621
620
            assert kind is not None
622
621
            if file_id is None:
624
623
            else:
625
624
                file_id = osutils.safe_file_id(file_id)
626
625
                inv.add_path(f, kind=kind, file_id=file_id)
627
 
        self._write_inventory(inv)
 
626
            self._inventory_is_modified = True
628
627
 
629
628
    @needs_tree_write_lock
630
629
    def _gather_kinds(self, files, kinds):
813
812
                to_revision = osutils.safe_revision_id(to_revision)
814
813
            merger.other_rev_id = to_revision
815
814
            if merger.other_rev_id is None:
816
 
                raise error.NoCommits(branch)
 
815
                raise errors.NoCommits(branch)
817
816
            self.branch.fetch(branch, last_revision=merger.other_rev_id)
818
817
            merger.other_basis = merger.other_rev_id
819
818
            merger.other_tree = self.branch.repository.revision_tree(
1775
1774
        if isinstance(files, basestring):
1776
1775
            files = [files]
1777
1776
 
1778
 
        inv = self.inventory
 
1777
        inv_delta = []
1779
1778
 
1780
1779
        new_files=set()
1781
1780
        unknown_files_in_directory=set()
1783
1782
        def recurse_directory_to_add_files(directory):
1784
1783
            # recurse directory and add all files
1785
1784
            # so we can check if they have changed.
1786
 
            for contained_dir_info in self.walkdirs(directory):
1787
 
                for file_info in contained_dir_info[1]:
1788
 
                    if file_info[2] == 'file':
1789
 
                        relpath = self.relpath(file_info[0])
1790
 
                        if file_info[4]: #is it versioned?
 
1785
            for parent_info, file_infos in\
 
1786
                osutils.walkdirs(self.abspath(directory),
 
1787
                    directory):
 
1788
                for relpath, basename, kind, lstat, abspath in file_infos:
 
1789
                    if kind == 'file':
 
1790
                        if self.path2id(relpath): #is it versioned?
1791
1791
                            new_files.add(relpath)
1792
1792
                        else:
1793
1793
                            unknown_files_in_directory.add(
1794
 
                                (relpath, None, file_info[2]))
 
1794
                                (relpath, None, kind))
1795
1795
 
1796
1796
        for filename in files:
1797
1797
            # Get file name into canonical form.
1798
 
            filename = self.relpath(self.abspath(filename))
 
1798
            abspath = self.abspath(filename)
 
1799
            filename = self.relpath(abspath)
1799
1800
            if len(filename) > 0:
1800
1801
                new_files.add(filename)
1801
 
                if osutils.isdir(filename) and len(os.listdir(filename)) > 0:
 
1802
                if osutils.isdir(abspath):
1802
1803
                    recurse_directory_to_add_files(filename)
1803
1804
        files = [f for f in new_files]
1804
1805
 
1818
1819
 
1819
1820
        # do this before any modifications
1820
1821
        for f in files:
1821
 
            fid = inv.path2id(f)
 
1822
            fid = self.path2id(f)
1822
1823
            message=None
1823
1824
            if not fid:
1824
1825
                message="%s is not versioned." % (f,)
1829
1830
                        new_status = 'I'
1830
1831
                    else:
1831
1832
                        new_status = '?'
1832
 
                    textui.show_status(new_status, inv[fid].kind, f,
 
1833
                    textui.show_status(new_status, self.kind(fid), f,
1833
1834
                                       to_file=to_file)
1834
1835
                # unversion file
1835
 
                del inv[fid]
 
1836
                inv_delta.append((f, None, fid, None))
1836
1837
                message="removed %s" % (f,)
1837
1838
 
1838
1839
            if not keep_files:
1852
1853
            # print only one message (if any) per file.
1853
1854
            if message is not None:
1854
1855
                note(message)
1855
 
        self._write_inventory(inv)
 
1856
        self.apply_inventory_delta(inv_delta)
1856
1857
 
1857
1858
    @needs_tree_write_lock
1858
1859
    def revert(self, filenames, old_tree=None, backups=True, 
1969
1970
        """
1970
1971
        raise NotImplementedError(self.unlock)
1971
1972
 
1972
 
    def update(self):
 
1973
    def update(self, change_reporter=None):
1973
1974
        """Update a working tree along its branch.
1974
1975
 
1975
1976
        This will update the branch if its bound too, which means we have
2005
2006
                old_tip = self.branch.update()
2006
2007
            else:
2007
2008
                old_tip = None
2008
 
            return self._update_tree(old_tip)
 
2009
            return self._update_tree(old_tip, change_reporter)
2009
2010
        finally:
2010
2011
            self.unlock()
2011
2012
 
2012
2013
    @needs_tree_write_lock
2013
 
    def _update_tree(self, old_tip=None):
 
2014
    def _update_tree(self, old_tip=None, change_reporter=None):
2014
2015
        """Update a tree to the master branch.
2015
2016
 
2016
2017
        :param old_tip: if supplied, the previous tip revision the branch,
2044
2045
                                      self.branch,
2045
2046
                                      to_tree,
2046
2047
                                      basis,
2047
 
                                      this_tree=self)
 
2048
                                      this_tree=self,
 
2049
                                      change_reporter=change_reporter)
2048
2050
            finally:
2049
2051
                basis.unlock()
2050
2052
            # TODO - dedup parents list with things merged by pull ?
2083
2085
            #       inventory and calls tree._write_inventory(). Ultimately we
2084
2086
            #       should be able to remove this extra flush.
2085
2087
            self.flush()
2086
 
            from bzrlib.revision import common_ancestor
2087
 
            try:
2088
 
                base_rev_id = common_ancestor(self.branch.last_revision(),
2089
 
                                              old_tip,
2090
 
                                              self.branch.repository)
2091
 
            except errors.NoCommonAncestor:
2092
 
                base_rev_id = None
 
2088
            graph = self.branch.repository.get_graph()
 
2089
            base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
 
2090
                                                old_tip)
2093
2091
            base_tree = self.branch.repository.revision_tree(base_rev_id)
2094
2092
            other_tree = self.branch.repository.revision_tree(old_tip)
2095
2093
            result += merge.merge_inner(
2096
2094
                                  self.branch,
2097
2095
                                  other_tree,
2098
2096
                                  base_tree,
2099
 
                                  this_tree=self)
 
2097
                                  this_tree=self,
 
2098
                                  change_reporter=change_reporter)
2100
2099
        return result
2101
2100
 
2102
2101
    def _write_hashcache_if_dirty(self):
2774
2773
# and not independently creatable, so are not registered.
2775
2774
_legacy_formats = [WorkingTreeFormat2(),
2776
2775
                   ]
2777
 
 
2778
 
 
2779
 
class WorkingTreeTestProviderAdapter(object):
2780
 
    """A tool to generate a suite testing multiple workingtree formats at once.
2781
 
 
2782
 
    This is done by copying the test once for each transport and injecting
2783
 
    the transport_server, transport_readonly_server, and workingtree_format
2784
 
    classes into each copy. Each copy is also given a new id() to make it
2785
 
    easy to identify.
2786
 
    """
2787
 
 
2788
 
    def __init__(self, transport_server, transport_readonly_server, formats):
2789
 
        self._transport_server = transport_server
2790
 
        self._transport_readonly_server = transport_readonly_server
2791
 
        self._formats = formats
2792
 
    
2793
 
    def _clone_test(self, test, bzrdir_format, workingtree_format, variation):
2794
 
        """Clone test for adaption."""
2795
 
        new_test = deepcopy(test)
2796
 
        new_test.transport_server = self._transport_server
2797
 
        new_test.transport_readonly_server = self._transport_readonly_server
2798
 
        new_test.bzrdir_format = bzrdir_format
2799
 
        new_test.workingtree_format = workingtree_format
2800
 
        def make_new_test_id():
2801
 
            new_id = "%s(%s)" % (test.id(), variation)
2802
 
            return lambda: new_id
2803
 
        new_test.id = make_new_test_id()
2804
 
        return new_test
2805
 
    
2806
 
    def adapt(self, test):
2807
 
        from bzrlib.tests import TestSuite
2808
 
        result = TestSuite()
2809
 
        for workingtree_format, bzrdir_format in self._formats:
2810
 
            new_test = self._clone_test(
2811
 
                test,
2812
 
                bzrdir_format,
2813
 
                workingtree_format, workingtree_format.__class__.__name__)
2814
 
            result.addTest(new_test)
2815
 
        return result