~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-30 05:50:28 UTC
  • mfrom: (4183.5.9 commit-uses-ric)
  • Revision ID: pqm@pqm.ubuntu.com-20090330055028-lhmncpzf7ebkd2yc
(robertc) Teach commit to use record_iter_changes for some commits.
        (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
324
324
            raise AssertionError("recording deletes not activated.")
325
325
        delta = (path, None, file_id, None)
326
326
        self._basis_delta.append(delta)
 
327
        self._any_changes = True
327
328
        return delta
328
329
 
329
330
    def will_record_deletes(self):
558
559
            has been generated against. Currently assumed to be the same
559
560
            as self.parents[0] - if it is not, errors may occur.
560
561
        :param iter_changes: An iter_changes iterator with the changes to apply
561
 
            to basis_revision_id.
 
562
            to basis_revision_id. The iterator must not include any items with
 
563
            a current kind of None - missing items must be either filtered out
 
564
            or errored-on beefore record_iter_changes sees the item.
562
565
        :param _entry_factory: Private method to bind entry_factory locally for
563
566
            performance.
564
 
        :return: None
 
567
        :return: A generator of (file_id, relpath, fs_hash) tuples for use with
 
568
            tree._observed_sha1.
565
569
        """
566
570
        # Create an inventory delta based on deltas between all the parents and
567
571
        # deltas between all the parent inventories. We use inventory delta's 
574
578
        # {file_id -> revision_id -> inventory entry, for entries in parent
575
579
        # trees that are not parents[0]
576
580
        parent_entries = {}
577
 
        revtrees = list(self.repository.revision_trees(self.parents))
 
581
        ghost_basis = False
 
582
        try:
 
583
            revtrees = list(self.repository.revision_trees(self.parents))
 
584
        except errors.NoSuchRevision:
 
585
            # one or more ghosts, slow path.
 
586
            revtrees = []
 
587
            for revision_id in self.parents:
 
588
                try:
 
589
                    revtrees.append(self.repository.revision_tree(revision_id))
 
590
                except errors.NoSuchRevision:
 
591
                    if not revtrees:
 
592
                        basis_revision_id = _mod_revision.NULL_REVISION
 
593
                        ghost_basis = True
 
594
                    revtrees.append(self.repository.revision_tree(
 
595
                        _mod_revision.NULL_REVISION))
578
596
        # The basis inventory from a repository 
579
597
        if revtrees:
580
598
            basis_inv = revtrees[0].inventory
582
600
            basis_inv = self.repository.revision_tree(
583
601
                _mod_revision.NULL_REVISION).inventory
584
602
        if len(self.parents) > 0:
585
 
            if basis_revision_id != self.parents[0]:
 
603
            if basis_revision_id != self.parents[0] and not ghost_basis:
586
604
                raise Exception(
587
605
                    "arbitrary basis parents not yet supported with merges")
588
606
            for revtree in revtrees[1:]:
592
610
                        continue
593
611
                    if change[2] not in merged_ids:
594
612
                        if change[0] is not None:
 
613
                            basis_entry = basis_inv[change[2]]
595
614
                            merged_ids[change[2]] = [
596
 
                                basis_inv[change[2]].revision,
 
615
                                # basis revid
 
616
                                basis_entry.revision,
 
617
                                # new tree revid
597
618
                                change[3].revision]
 
619
                            parent_entries[change[2]] = {
 
620
                                # basis parent
 
621
                                basis_entry.revision:basis_entry,
 
622
                                # this parent 
 
623
                                change[3].revision:change[3],
 
624
                                }
598
625
                        else:
599
626
                            merged_ids[change[2]] = [change[3].revision]
600
 
                        parent_entries[change[2]] = {change[3].revision:change[3]}
 
627
                            parent_entries[change[2]] = {change[3].revision:change[3]}
601
628
                    else:
602
629
                        merged_ids[change[2]].append(change[3].revision)
603
630
                        parent_entries[change[2]][change[3].revision] = change[3]
628
655
            # inv delta  change: (file_id, (path_in_source, path_in_target),
629
656
            #   changed_content, versioned, parent, name, kind,
630
657
            #   executable)
631
 
            basis_entry = basis_inv[file_id]
632
 
            change = (file_id,
633
 
                (basis_inv.id2path(file_id), tree.id2path(file_id)),
634
 
                False, (True, True),
635
 
                (basis_entry.parent_id, basis_entry.parent_id),
636
 
                (basis_entry.name, basis_entry.name),
637
 
                (basis_entry.kind, basis_entry.kind),
638
 
                (basis_entry.executable, basis_entry.executable))
639
 
            changes[file_id] = (change, merged_ids[file_id])
 
658
            try:
 
659
                basis_entry = basis_inv[file_id]
 
660
            except errors.NoSuchId:
 
661
                # a change from basis->some_parents but file_id isn't in basis
 
662
                # so was new in the merge, which means it must have changed
 
663
                # from basis -> current, and as it hasn't the add was reverted
 
664
                # by the user. So we discard this change.
 
665
                pass
 
666
            else:
 
667
                change = (file_id,
 
668
                    (basis_inv.id2path(file_id), tree.id2path(file_id)),
 
669
                    False, (True, True),
 
670
                    (basis_entry.parent_id, basis_entry.parent_id),
 
671
                    (basis_entry.name, basis_entry.name),
 
672
                    (basis_entry.kind, basis_entry.kind),
 
673
                    (basis_entry.executable, basis_entry.executable))
 
674
                changes[file_id] = (change, merged_ids[file_id])
640
675
        # changes contains tuples with the change and a set of inventory
641
676
        # candidates for the file.
642
677
        # inv delta is:
723
758
                    try:
724
759
                        entry.text_sha1, entry.text_size = self._add_text_to_weave(
725
760
                            file_id, lines, heads, nostore_sha)
 
761
                        yield file_id, change[1][1], (entry.text_sha1, stat_value)
726
762
                    except errors.ExistingContent:
727
763
                        # No content change against a carry_over parent
 
764
                        # Perhaps this should also yield a fs hash update?
728
765
                        carried_over = True
729
766
                        entry.text_size = parent_entry.text_size
730
767
                        entry.text_sha1 = parent_entry.text_sha1
733
770
                    entry.symlink_target = tree.get_symlink_target(file_id)
734
771
                    if (carry_over_possible and
735
772
                        parent_entry.symlink_target == entry.symlink_target):
736
 
                            carried_over = True
 
773
                        carried_over = True
737
774
                    else:
738
775
                        self._add_text_to_weave(change[0], [], heads, None)
739
776
                elif kind == 'directory':
745
782
                        if change[1][1] != '' or self.repository.supports_rich_root():
746
783
                            self._add_text_to_weave(change[0], [], heads, None)
747
784
                elif kind == 'tree-reference':
748
 
                    raise AssertionError('unknown kind %r' % kind)
 
785
                    if not self.repository._format.supports_tree_reference:
 
786
                        # This isn't quite sane as an error, but we shouldn't
 
787
                        # ever see this code path in practice: tree's don't
 
788
                        # permit references when the repo doesn't support tree
 
789
                        # references.
 
790
                        raise errors.UnsupportedOperation(tree.add_reference,
 
791
                            self.repository)
 
792
                    entry.reference_revision = \
 
793
                        tree.get_reference_revision(change[0])
 
794
                    if (carry_over_possible and
 
795
                        parent_entry.reference_revision == reference_revision):
 
796
                        carried_over = True
 
797
                    else:
 
798
                        self._add_text_to_weave(change[0], [], heads, None)
749
799
                else:
750
800
                    raise AssertionError('unknown kind %r' % kind)
751
801
                if not carried_over: