~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-02-10 16:25:28 UTC
  • mfrom: (5020.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20100210162528-00g29u0ex6vzv914
(gerard) Update performs two merges in a more logical order but stop
        on conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
2250
2250
        # We MUST save it even if an error occurs, because otherwise the users
2251
2251
        # local work is unreferenced and will appear to have been lost.
2252
2252
        #
2253
 
        result = 0
 
2253
        nb_conflicts = 0
2254
2254
        try:
2255
2255
            last_rev = self.get_parent_ids()[0]
2256
2256
        except IndexError:
2260
2260
        else:
2261
2261
            if revision not in self.branch.revision_history():
2262
2262
                raise errors.NoSuchRevision(self.branch, 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
 
2263
2279
        if last_rev != _mod_revision.ensure_null(revision):
2264
 
            # merge tree state up to specified 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
 
2265
2285
            basis = self.basis_tree()
2266
2286
            basis.lock_read()
2267
2287
            try:
2268
 
                to_tree = self.branch.repository.revision_tree(revision)
2269
 
                to_root_id = to_tree.get_root_id()
2270
2288
                if (basis.inventory.root is None
2271
2289
                    or basis.inventory.root.file_id != to_root_id):
2272
2290
                    self.set_root_id(to_root_id)
2273
2291
                    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)
2281
2292
            finally:
2282
2293
                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)
2283
2305
            # TODO - dedup parents list with things merged by pull ?
2284
2306
            # reuse the tree we've updated to to set the basis:
2285
2307
            parent_trees = [(revision, to_tree)]
2292
2314
            for parent in merges:
2293
2315
                parent_trees.append(
2294
2316
                    (parent, self.branch.repository.revision_tree(parent)))
2295
 
            if (old_tip is not None and not _mod_revision.is_null(old_tip)):
 
2317
            if not _mod_revision.is_null(old_tip):
2296
2318
                parent_trees.append(
2297
2319
                    (old_tip, self.branch.repository.revision_tree(old_tip)))
2298
2320
            self.set_parent_trees(parent_trees)
2299
2321
            last_rev = parent_trees[0][0]
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
 
2322
        return nb_conflicts
2331
2323
 
2332
2324
    def _write_hashcache_if_dirty(self):
2333
2325
        """Write out the hashcache if it is dirty."""