~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Andrew Bennetts
  • Date: 2010-01-15 03:58:20 UTC
  • mfrom: (4963 +trunk)
  • mto: (4973.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4975.
  • Revision ID: andrew.bennetts@canonical.com-20100115035820-ilb3t36swgzq6v1l
MergeĀ lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
1627
1627
                                this_tree=self,
1628
1628
                                pb=pb,
1629
1629
                                change_reporter=change_reporter)
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())
 
1630
                    basis_root_id = basis_tree.get_root_id()
 
1631
                    new_root_id = new_basis_tree.get_root_id()
 
1632
                    if basis_root_id != new_root_id:
 
1633
                        self.set_root_id(new_root_id)
1633
1634
                finally:
1634
1635
                    pb.finished()
1635
1636
                    basis_tree.unlock()
2191
2192
        """
2192
2193
        raise NotImplementedError(self.unlock)
2193
2194
 
2194
 
    def update(self, change_reporter=None, possible_transports=None):
 
2195
    _marker = object()
 
2196
 
 
2197
    def update(self, change_reporter=None, possible_transports=None,
 
2198
               revision=None, old_tip=_marker):
2195
2199
        """Update a working tree along its branch.
2196
2200
 
2197
2201
        This will update the branch if its bound too, which means we have
2215
2219
        - Merge current state -> basis tree of the master w.r.t. the old tree
2216
2220
          basis.
2217
2221
        - Do a 'normal' merge of the old branch basis if it is relevant.
 
2222
 
 
2223
        :param revision: The target revision to update to. Must be in the
 
2224
            revision history.
 
2225
        :param old_tip: If branch.update() has already been run, the value it
 
2226
            returned (old tip of the branch or None). _marker is used
 
2227
            otherwise.
2218
2228
        """
2219
2229
        if self.branch.get_bound_location() is not None:
2220
2230
            self.lock_write()
2221
 
            update_branch = True
 
2231
            update_branch = (old_tip is self._marker)
2222
2232
        else:
2223
2233
            self.lock_tree_write()
2224
2234
            update_branch = False
2226
2236
            if update_branch:
2227
2237
                old_tip = self.branch.update(possible_transports)
2228
2238
            else:
2229
 
                old_tip = None
2230
 
            return self._update_tree(old_tip, change_reporter)
 
2239
                if old_tip is self._marker:
 
2240
                    old_tip = None
 
2241
            return self._update_tree(old_tip, change_reporter, revision)
2231
2242
        finally:
2232
2243
            self.unlock()
2233
2244
 
2234
2245
    @needs_tree_write_lock
2235
 
    def _update_tree(self, old_tip=None, change_reporter=None):
 
2246
    def _update_tree(self, old_tip=None, change_reporter=None, revision=None):
2236
2247
        """Update a tree to the master branch.
2237
2248
 
2238
2249
        :param old_tip: if supplied, the previous tip revision the branch,
2253
2264
            last_rev = self.get_parent_ids()[0]
2254
2265
        except IndexError:
2255
2266
            last_rev = _mod_revision.NULL_REVISION
2256
 
        if last_rev != _mod_revision.ensure_null(self.branch.last_revision()):
2257
 
            # merge tree state up to new branch tip.
 
2267
        if revision is None:
 
2268
            revision = self.branch.last_revision()
 
2269
        else:
 
2270
            if revision not in self.branch.revision_history():
 
2271
                raise errors.NoSuchRevision(self.branch, revision)
 
2272
        if last_rev != _mod_revision.ensure_null(revision):
 
2273
            # merge tree state up to specified revision.
2258
2274
            basis = self.basis_tree()
2259
2275
            basis.lock_read()
2260
2276
            try:
2261
 
                to_tree = self.branch.basis_tree()
2262
 
                if basis.inventory.root is None:
2263
 
                    self.set_root_id(to_tree.get_root_id())
 
2277
                to_tree = self.branch.repository.revision_tree(revision)
 
2278
                to_root_id = to_tree.get_root_id()
 
2279
                if (basis.inventory.root is None
 
2280
                    or basis.inventory.root.file_id != to_root_id):
 
2281
                    self.set_root_id(to_root_id)
2264
2282
                    self.flush()
2265
2283
                result += merge.merge_inner(
2266
2284
                                      self.branch,
2268
2286
                                      basis,
2269
2287
                                      this_tree=self,
2270
2288
                                      change_reporter=change_reporter)
 
2289
                self.set_last_revision(revision)
2271
2290
            finally:
2272
2291
                basis.unlock()
2273
2292
            # TODO - dedup parents list with things merged by pull ?
2274
2293
            # reuse the tree we've updated to to set the basis:
2275
 
            parent_trees = [(self.branch.last_revision(), to_tree)]
 
2294
            parent_trees = [(revision, to_tree)]
2276
2295
            merges = self.get_parent_ids()[1:]
2277
2296
            # Ideally we ask the tree for the trees here, that way the working
2278
2297
            # tree can decide whether to give us the entire tree or give us a
2308
2327
            #       should be able to remove this extra flush.
2309
2328
            self.flush()
2310
2329
            graph = self.branch.repository.get_graph()
2311
 
            base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
2312
 
                                                old_tip)
 
2330
            base_rev_id = graph.find_unique_lca(revision, old_tip)
2313
2331
            base_tree = self.branch.repository.revision_tree(base_rev_id)
2314
2332
            other_tree = self.branch.repository.revision_tree(old_tip)
2315
2333
            result += merge.merge_inner(