~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/reconcile.py

  • Committer: Aaron Bentley
  • Date: 2007-08-25 15:47:27 UTC
  • mto: This revision was merged to the branch mainline in revision 2905.
  • Revision ID: aaron.bentley@utoronto.ca-20070825154727-2gstd0e1odldnlpz
Fix knit file parents to follow parentage from revision/inventory XML

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
__all__ = ['reconcile', 'Reconciler', 'RepoReconciler', 'KnitReconciler']
21
21
 
22
22
 
23
 
from bzrlib import ui
 
23
from bzrlib import (
 
24
    graph,
 
25
    ui,
 
26
    repository,
 
27
    )
24
28
from bzrlib.trace import mutter
25
29
from bzrlib.tsort import TopoSorter
26
30
 
274
278
 
275
279
    def _reconcile_steps(self):
276
280
        """Perform the steps to reconcile this repository."""
 
281
        self._load_indexes()
277
282
        if self.thorough:
278
 
            self._load_indexes()
279
283
            self._gc_inventory()
 
284
        self._fix_text_parents()
280
285
 
281
286
    def _load_indexes(self):
282
287
        """Load indexes for the reconciliation."""
336
341
        self.garbage_inventories = len(garbage)
337
342
        for revision_id in garbage:
338
343
            mutter('Garbage inventory {%s} found.', revision_id)
 
344
 
 
345
    def _fix_text_parents(self):
 
346
        transaction = self.repo.get_transaction()
 
347
        revision_parents = repository._RevisionParentsProvider(self.repo)
 
348
        revision_graph = graph.Graph(revision_parents)
 
349
        revision_versions = {}
 
350
        for file_id in self.repo.weave_store:
 
351
            vf = self.repo.weave_store.get_weave(file_id, transaction)
 
352
            bad_ancestors = self.repo.find_bad_ancestors(
 
353
                self.revisions.versions(), file_id, vf, revision_versions,
 
354
                revision_parents)
 
355
            if len(bad_ancestors) == 0:
 
356
                continue
 
357
            new_vf = self.repo.weave_store.get_empty('temp:%s' % file_id,
 
358
                self.transaction)
 
359
            for version in vf.versions():
 
360
                parents = vf.get_parents(version)
 
361
                for parent_id in parents:
 
362
                    if (parent_id in bad_ancestors and
 
363
                        version in bad_ancestors[parent_id]):
 
364
                        parents = self._find_correct_parents(version,
 
365
                            file_id, revision_versions, revision_graph)
 
366
                        break
 
367
                new_vf.add_lines(version, parents, vf.get_lines(version))
 
368
            self.repo.weave_store.copy(new_vf, file_id, self.transaction)
 
369
            self.repo.weave_store.delete('temp:%s' % file_id, self.transaction)
 
370
 
 
371
    def _find_correct_parents(self, revision_id, file_id, revision_versions,
 
372
                              revision_graph):
 
373
        parents = []
 
374
        rev_parents = revision_graph.get_parents([revision_id])[0]
 
375
        if rev_parents is None:
 
376
            return []
 
377
        for parent_id in rev_parents:
 
378
            try:
 
379
                parent_id = revision_versions[parent_id][file_id]
 
380
            except KeyError:
 
381
                continue
 
382
            if parent_id not in parents:
 
383
                parents.append(parent_id)
 
384
        non_heads = set()
 
385
        for num, parent in enumerate(parents):
 
386
            for other_parent in parents[num+1:]:
 
387
                if revision_graph.is_ancestor(parent, other_parent):
 
388
                    non_heads.add(parent)
 
389
                if revision_graph.is_ancestor(other_parent, parent):
 
390
                    non_heads.add(other_parent)
 
391
        return [p for p in parents if p not in non_heads]