~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Neil Martinsen-Burrell
  • Date: 2010-01-05 02:13:02 UTC
  • mto: This revision was merged to the branch mainline in revision 4938.
  • Revision ID: nmb@wartburg.edu-20100105021302-lqr16qpar3f38hpf
from review comments: improve splitting, add test that handler is present, use build_tree in tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
111
111
 
112
112
 
113
113
MERGE_MODIFIED_HEADER_1 = "BZR merge-modified list format 1"
114
 
# TODO: Modifying the conflict objects or their type is currently nearly
115
 
# impossible as there is no clear relationship between the working tree format
116
 
# and the conflict list file format.
117
114
CONFLICT_HEADER_1 = "BZR conflict list format 1"
118
115
 
119
116
ERROR_PATH_NOT_FOUND = 3    # WindowsError errno code, equivalent to ENOENT
1630
1627
                                this_tree=self,
1631
1628
                                pb=pb,
1632
1629
                                change_reporter=change_reporter)
1633
 
                    basis_root_id = basis_tree.get_root_id()
1634
 
                    new_root_id = new_basis_tree.get_root_id()
1635
 
                    if basis_root_id != new_root_id:
1636
 
                        self.set_root_id(new_root_id)
 
1630
                    if (basis_tree.inventory.root is None and
 
1631
                        new_basis_tree.inventory.root is not None):
 
1632
                        self.set_root_id(new_basis_tree.get_root_id())
1637
1633
                finally:
1638
1634
                    pb.finished()
1639
1635
                    basis_tree.unlock()
1745
1741
        r"""Check whether the filename matches an ignore pattern.
1746
1742
 
1747
1743
        Patterns containing '/' or '\' need to match the whole path;
1748
 
        others match against only the last component.  Patterns starting
1749
 
        with '!' are ignore exceptions.  Exceptions take precedence
1750
 
        over regular patterns and cause the filename to not be ignored.
 
1744
        others match against only the last component.
1751
1745
 
1752
1746
        If the file is ignored, returns the pattern which caused it to
1753
1747
        be ignored, otherwise None.  So this can simply be used as a
1754
1748
        boolean if desired."""
1755
1749
        if getattr(self, '_ignoreglobster', None) is None:
1756
 
            self._ignoreglobster = globbing.ExceptionGlobster(self.get_ignore_list())
 
1750
            self._ignoreglobster = globbing.Globster(self.get_ignore_list())
1757
1751
        return self._ignoreglobster.match(filename)
1758
1752
 
1759
1753
    def kind(self, file_id):
1907
1901
            # revision_id is set. We must check for this full string, because a
1908
1902
            # root node id can legitimately look like 'revision_id' but cannot
1909
1903
            # contain a '"'.
1910
 
            xml = self.branch.repository._get_inventory_xml(new_revision)
 
1904
            xml = self.branch.repository.get_inventory_xml(new_revision)
1911
1905
            firstline = xml.split('\n', 1)[0]
1912
1906
            if (not 'revision_id="' in firstline or
1913
1907
                'format="7"' not in firstline):
2197
2191
        """
2198
2192
        raise NotImplementedError(self.unlock)
2199
2193
 
2200
 
    _marker = object()
2201
 
 
2202
 
    def update(self, change_reporter=None, possible_transports=None,
2203
 
               revision=None, old_tip=_marker):
 
2194
    def update(self, change_reporter=None, possible_transports=None):
2204
2195
        """Update a working tree along its branch.
2205
2196
 
2206
2197
        This will update the branch if its bound too, which means we have
2224
2215
        - Merge current state -> basis tree of the master w.r.t. the old tree
2225
2216
          basis.
2226
2217
        - Do a 'normal' merge of the old branch basis if it is relevant.
2227
 
 
2228
 
        :param revision: The target revision to update to. Must be in the
2229
 
            revision history.
2230
 
        :param old_tip: If branch.update() has already been run, the value it
2231
 
            returned (old tip of the branch or None). _marker is used
2232
 
            otherwise.
2233
2218
        """
2234
2219
        if self.branch.get_bound_location() is not None:
2235
2220
            self.lock_write()
2236
 
            update_branch = (old_tip is self._marker)
 
2221
            update_branch = True
2237
2222
        else:
2238
2223
            self.lock_tree_write()
2239
2224
            update_branch = False
2241
2226
            if update_branch:
2242
2227
                old_tip = self.branch.update(possible_transports)
2243
2228
            else:
2244
 
                if old_tip is self._marker:
2245
 
                    old_tip = None
2246
 
            return self._update_tree(old_tip, change_reporter, revision)
 
2229
                old_tip = None
 
2230
            return self._update_tree(old_tip, change_reporter)
2247
2231
        finally:
2248
2232
            self.unlock()
2249
2233
 
2250
2234
    @needs_tree_write_lock
2251
 
    def _update_tree(self, old_tip=None, change_reporter=None, revision=None):
 
2235
    def _update_tree(self, old_tip=None, change_reporter=None):
2252
2236
        """Update a tree to the master branch.
2253
2237
 
2254
2238
        :param old_tip: if supplied, the previous tip revision the branch,
2269
2253
            last_rev = self.get_parent_ids()[0]
2270
2254
        except IndexError:
2271
2255
            last_rev = _mod_revision.NULL_REVISION
2272
 
        if revision is None:
2273
 
            revision = self.branch.last_revision()
2274
 
        else:
2275
 
            if revision not in self.branch.revision_history():
2276
 
                raise errors.NoSuchRevision(self.branch, revision)
2277
 
        if last_rev != _mod_revision.ensure_null(revision):
2278
 
            # merge tree state up to specified revision.
 
2256
        if last_rev != _mod_revision.ensure_null(self.branch.last_revision()):
 
2257
            # merge tree state up to new branch tip.
2279
2258
            basis = self.basis_tree()
2280
2259
            basis.lock_read()
2281
2260
            try:
2282
 
                to_tree = self.branch.repository.revision_tree(revision)
2283
 
                to_root_id = to_tree.get_root_id()
2284
 
                if (basis.inventory.root is None
2285
 
                    or basis.inventory.root.file_id != to_root_id):
2286
 
                    self.set_root_id(to_root_id)
 
2261
                to_tree = self.branch.basis_tree()
 
2262
                if basis.inventory.root is None:
 
2263
                    self.set_root_id(to_tree.get_root_id())
2287
2264
                    self.flush()
2288
2265
                result += merge.merge_inner(
2289
2266
                                      self.branch,
2291
2268
                                      basis,
2292
2269
                                      this_tree=self,
2293
2270
                                      change_reporter=change_reporter)
2294
 
                self.set_last_revision(revision)
2295
2271
            finally:
2296
2272
                basis.unlock()
2297
2273
            # TODO - dedup parents list with things merged by pull ?
2298
2274
            # reuse the tree we've updated to to set the basis:
2299
 
            parent_trees = [(revision, to_tree)]
 
2275
            parent_trees = [(self.branch.last_revision(), to_tree)]
2300
2276
            merges = self.get_parent_ids()[1:]
2301
2277
            # Ideally we ask the tree for the trees here, that way the working
2302
2278
            # tree can decide whether to give us the entire tree or give us a
2332
2308
            #       should be able to remove this extra flush.
2333
2309
            self.flush()
2334
2310
            graph = self.branch.repository.get_graph()
2335
 
            base_rev_id = graph.find_unique_lca(revision, old_tip)
 
2311
            base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
 
2312
                                                old_tip)
2336
2313
            base_tree = self.branch.repository.revision_tree(base_rev_id)
2337
2314
            other_tree = self.branch.repository.revision_tree(old_tip)
2338
2315
            result += merge.merge_inner(