/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/workingtree.py

  • Committer: Martin Pool
  • Date: 2010-02-09 19:04:02 UTC
  • mfrom: (5010 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5019.
  • Revision ID: mbp@canonical.com-20100209190402-2xbzrchmb4dfi2j7
Resolve conflicts with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
WorkingTree.open(dir).
30
30
"""
31
31
 
 
32
# TODO: Give the workingtree sole responsibility for the working inventory;
 
33
# remove the variable and references to it from the branch.  This may require
 
34
# updating the commit code so as to update the inventory within the working
 
35
# copy, and making sure there's only one WorkingTree for any directory on disk.
 
36
# At the moment they may alias the inventory and have old copies of it in
 
37
# memory.  (Now done? -- mbp 20060309)
32
38
 
33
39
from cStringIO import StringIO
34
40
import os
95
101
from bzrlib.filters import filtered_input_file
96
102
from bzrlib.trace import mutter, note
97
103
from bzrlib.transport.local import LocalTransport
 
104
from bzrlib.progress import ProgressPhase
98
105
from bzrlib.revision import CURRENT_REVISION
99
106
from bzrlib.rio import RioReader, rio_file, Stanza
100
107
from bzrlib.symbol_versioning import (
167
174
        return ''
168
175
 
169
176
 
170
 
class WorkingTree(bzrlib.mutabletree.MutableTree,
171
 
    bzrdir.ControlComponent):
 
177
class WorkingTree(bzrlib.mutabletree.MutableTree):
172
178
    """Working copy tree.
173
179
 
174
180
    The inventory is held in the `Branch` working-inventory, and the
247
253
        self._rules_searcher = None
248
254
        self.views = self._make_views()
249
255
 
250
 
    @property
251
 
    def user_transport(self):
252
 
        return self.bzrdir.user_transport
253
 
 
254
 
    @property
255
 
    def control_transport(self):
256
 
        return self._transport
257
 
 
258
256
    def _detect_case_handling(self):
259
257
        wt_trans = self.bzrdir.get_workingtree_transport(None)
260
258
        try:
1096
1094
        tree_transport = self.bzrdir.root_transport.clone(sub_path)
1097
1095
        if tree_transport.base != branch_transport.base:
1098
1096
            tree_bzrdir = format.initialize_on_transport(tree_transport)
1099
 
            branch.BranchReferenceFormat().initialize(tree_bzrdir,
1100
 
                target_branch=new_branch)
 
1097
            branch.BranchReferenceFormat().initialize(tree_bzrdir, new_branch)
1101
1098
        else:
1102
1099
            tree_bzrdir = branch_bzrdir
1103
1100
        wt = tree_bzrdir.create_workingtree(_mod_revision.NULL_REVISION)
1141
1138
        This does not include files that have been deleted in this
1142
1139
        tree. Skips the control directory.
1143
1140
 
1144
 
        :param include_root: if True, return an entry for the root
 
1141
        :param include_root: if True, do not return an entry for the root
1145
1142
        :param from_dir: start from this directory or None for the root
1146
1143
        :param recursive: whether to recurse into subdirectories or not
1147
1144
        """
2253
2250
        # We MUST save it even if an error occurs, because otherwise the users
2254
2251
        # local work is unreferenced and will appear to have been lost.
2255
2252
        #
2256
 
        nb_conflicts = 0
 
2253
        result = 0
2257
2254
        try:
2258
2255
            last_rev = self.get_parent_ids()[0]
2259
2256
        except IndexError:
2260
2257
            last_rev = _mod_revision.NULL_REVISION
2261
2258
        if revision is None:
2262
2259
            revision = self.branch.last_revision()
2263
 
 
2264
 
        old_tip = old_tip or _mod_revision.NULL_REVISION
2265
 
 
2266
 
        if not _mod_revision.is_null(old_tip) and old_tip != last_rev:
2267
 
            # the branch we are bound to was updated
2268
 
            # merge those changes in first
2269
 
            base_tree  = self.basis_tree()
2270
 
            other_tree = self.branch.repository.revision_tree(old_tip)
2271
 
            nb_conflicts = merge.merge_inner(self.branch, other_tree,
2272
 
                                             base_tree, this_tree=self,
2273
 
                                             change_reporter=change_reporter)
2274
 
            if nb_conflicts:
2275
 
                self.add_parent_tree((old_tip, other_tree))
2276
 
                trace.note('Rerun update after fixing the conflicts.')
2277
 
                return nb_conflicts
2278
 
 
 
2260
        else:
 
2261
            if revision not in self.branch.revision_history():
 
2262
                raise errors.NoSuchRevision(self.branch, revision)
2279
2263
        if last_rev != _mod_revision.ensure_null(revision):
2280
 
            # the working tree is up to date with the branch
2281
 
            # we can merge the specified revision from master
2282
 
            to_tree = self.branch.repository.revision_tree(revision)
2283
 
            to_root_id = to_tree.get_root_id()
2284
 
 
 
2264
            # merge tree state up to specified revision.
2285
2265
            basis = self.basis_tree()
2286
2266
            basis.lock_read()
2287
2267
            try:
 
2268
                to_tree = self.branch.repository.revision_tree(revision)
 
2269
                to_root_id = to_tree.get_root_id()
2288
2270
                if (basis.inventory.root is None
2289
2271
                    or basis.inventory.root.file_id != to_root_id):
2290
2272
                    self.set_root_id(to_root_id)
2291
2273
                    self.flush()
 
2274
                result += merge.merge_inner(
 
2275
                                      self.branch,
 
2276
                                      to_tree,
 
2277
                                      basis,
 
2278
                                      this_tree=self,
 
2279
                                      change_reporter=change_reporter)
 
2280
                self.set_last_revision(revision)
2292
2281
            finally:
2293
2282
                basis.unlock()
2294
 
 
2295
 
            # determine the branch point
2296
 
            graph = self.branch.repository.get_graph()
2297
 
            base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
2298
 
                                                last_rev)
2299
 
            base_tree = self.branch.repository.revision_tree(base_rev_id)
2300
 
 
2301
 
            nb_conflicts = merge.merge_inner(self.branch, to_tree, base_tree,
2302
 
                                             this_tree=self,
2303
 
                                             change_reporter=change_reporter)
2304
 
            self.set_last_revision(revision)
2305
2283
            # TODO - dedup parents list with things merged by pull ?
2306
2284
            # reuse the tree we've updated to to set the basis:
2307
2285
            parent_trees = [(revision, to_tree)]
2314
2292
            for parent in merges:
2315
2293
                parent_trees.append(
2316
2294
                    (parent, self.branch.repository.revision_tree(parent)))
2317
 
            if not _mod_revision.is_null(old_tip):
 
2295
            if (old_tip is not None and not _mod_revision.is_null(old_tip)):
2318
2296
                parent_trees.append(
2319
2297
                    (old_tip, self.branch.repository.revision_tree(old_tip)))
2320
2298
            self.set_parent_trees(parent_trees)
2321
2299
            last_rev = parent_trees[0][0]
2322
 
        return nb_conflicts
 
2300
        else:
 
2301
            # the working tree had the same last-revision as the master
 
2302
            # branch did. We may still have pivot local work from the local
 
2303
            # branch into old_tip:
 
2304
            if (old_tip is not None and not _mod_revision.is_null(old_tip)):
 
2305
                self.add_parent_tree_id(old_tip)
 
2306
        if (old_tip is not None and not _mod_revision.is_null(old_tip)
 
2307
            and old_tip != last_rev):
 
2308
            # our last revision was not the prior branch last revision
 
2309
            # and we have converted that last revision to a pending merge.
 
2310
            # base is somewhere between the branch tip now
 
2311
            # and the now pending merge
 
2312
 
 
2313
            # Since we just modified the working tree and inventory, flush out
 
2314
            # the current state, before we modify it again.
 
2315
            # TODO: jam 20070214 WorkingTree3 doesn't require this, dirstate
 
2316
            #       requires it only because TreeTransform directly munges the
 
2317
            #       inventory and calls tree._write_inventory(). Ultimately we
 
2318
            #       should be able to remove this extra flush.
 
2319
            self.flush()
 
2320
            graph = self.branch.repository.get_graph()
 
2321
            base_rev_id = graph.find_unique_lca(revision, old_tip)
 
2322
            base_tree = self.branch.repository.revision_tree(base_rev_id)
 
2323
            other_tree = self.branch.repository.revision_tree(old_tip)
 
2324
            result += merge.merge_inner(
 
2325
                                  self.branch,
 
2326
                                  other_tree,
 
2327
                                  base_tree,
 
2328
                                  this_tree=self,
 
2329
                                  change_reporter=change_reporter)
 
2330
        return result
2323
2331
 
2324
2332
    def _write_hashcache_if_dirty(self):
2325
2333
        """Write out the hashcache if it is dirty."""