~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit.py

  • Committer: Martin Pool
  • Date: 2007-10-10 00:21:57 UTC
  • mfrom: (2900 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2901.
  • Revision ID: mbp@sourcefrog.net-20071010002157-utci0x44m2w47wgd
merge news

Show diffs side-by-side

added added

removed removed

Lines of Context:
247
247
        self.local = local
248
248
        self.master_branch = None
249
249
        self.master_locked = False
 
250
        self.recursive = recursive
250
251
        self.rev_id = None
251
252
        if specific_files is not None:
252
253
            self.specific_files = sorted(
255
256
            self.specific_files = None
256
257
        self.specific_file_ids = None
257
258
        self.allow_pointless = allow_pointless
258
 
        self.recursive = recursive
259
259
        self.revprops = revprops
260
260
        self.message_callback = message_callback
261
261
        self.timestamp = timestamp
289
289
 
290
290
            # If provided, ensure the specified files are versioned
291
291
            if self.specific_files is not None:
292
 
                # Note: This routine
293
 
                # is being called because it raises PathNotVerisonedError
294
 
                # as a side effect of finding the IDs. We later use the ids we
295
 
                # found as input to the working tree inventory iterator, so we
296
 
                # only consider those ids rather than examining the whole tree
297
 
                # again.
 
292
                # Note: This routine is being called because it raises
 
293
                # PathNotVersionedError as a side effect of finding the IDs. We
 
294
                # later use the ids we found as input to the working tree
 
295
                # inventory iterator, so we only consider those ids rather than
 
296
                # examining the whole tree again.
298
297
                # XXX: Dont we have filter_unversioned to do this more
299
298
                # cheaply?
300
299
                self.specific_file_ids = tree.find_ids_across_trees(
650
649
        if specific_files:
651
650
            for path, old_ie in self.basis_inv.iter_entries():
652
651
                if old_ie.file_id in self.builder.new_inventory:
 
652
                    # already added - skip.
653
653
                    continue
654
654
                if is_inside_any(specific_files, path):
 
655
                    # was inside the selected path, if not present it has been
 
656
                    # deleted so skip.
655
657
                    continue
656
658
                if old_ie.kind == 'directory':
657
659
                    self._next_progress_entry()
 
660
                # not in final inv yet, was not in the selected files, so is an
 
661
                # entry to be preserved unaltered.
658
662
                ie = old_ie.copy()
659
663
                # Note: specific file commits after a merge are currently
660
664
                # prohibited. This test is for sanity/safety in case it's
661
665
                # required after that changes.
662
666
                if len(self.parents) > 1:
663
667
                    ie.revision = None
664
 
                if self.builder.record_entry_contents(ie, self.parent_invs, path,
665
 
                    self.basis_tree):
 
668
                delta, version_recorded = self.builder.record_entry_contents(
 
669
                    ie, self.parent_invs, path, self.basis_tree, None)
 
670
                if version_recorded:
666
671
                    self.any_entries_changed = True
667
672
 
668
673
        # note that deletes have occurred
686
691
        deleted_paths = set()
687
692
        work_inv = self.work_tree.inventory
688
693
        assert work_inv.root is not None
 
694
        # XXX: Note that entries may have the wrong kind.
689
695
        entries = work_inv.iter_entries_by_dir(
690
696
            specific_file_ids=self.specific_file_ids, yield_parents=True)
691
697
        if not self.builder.record_root_entry:
704
710
            # deleted files matching that filter.
705
711
            if is_inside_any(deleted_paths, path):
706
712
                continue
707
 
            if not self.work_tree.has_filename(path):
708
 
                deleted_paths.add(path)
709
 
                self.reporter.missing(path)
710
 
                deleted_ids.append(file_id)
711
 
                continue
712
 
            try:
713
 
                kind = self.work_tree.kind(file_id)
714
 
                # TODO: specific_files filtering before nested tree processing
715
 
                if kind == 'tree-reference' and self.recursive == 'down':
716
 
                    self._commit_nested_tree(file_id, path)
717
 
            except errors.NoSuchFile:
718
 
                pass
 
713
            content_summary = self.work_tree.path_content_summary(path)
 
714
            if not specific_files or is_inside_any(specific_files, path):
 
715
                if content_summary[0] == 'missing':
 
716
                    deleted_paths.add(path)
 
717
                    self.reporter.missing(path)
 
718
                    deleted_ids.append(file_id)
 
719
                    continue
 
720
            # TODO: have the builder do the nested commit just-in-time IF and
 
721
            # only if needed.
 
722
            if content_summary[0] == 'tree-reference':
 
723
                # enforce repository nested tree policy.
 
724
                if (not self.work_tree.supports_tree_reference() or
 
725
                    # repository does not support it either.
 
726
                    not self.branch.repository._format.supports_tree_reference):
 
727
                    content_summary = ('directory',) + content_summary[1:]
 
728
            kind = content_summary[0]
 
729
            # TODO: specific_files filtering before nested tree processing
 
730
            if kind == 'tree-reference':
 
731
                if self.recursive == 'down':
 
732
                    nested_revision_id = self._commit_nested_tree(
 
733
                        file_id, path)
 
734
                    content_summary = content_summary[:3] + (
 
735
                        nested_revision_id,)
 
736
                else:
 
737
                    content_summary = content_summary[:3] + (
 
738
                        self.work_tree.get_reference_revision(file_id),)
719
739
 
720
740
            # Record an entry for this item
721
741
            # Note: I don't particularly want to have the existing_ie
723
743
            # without it thanks to a unicode normalisation issue. :-(
724
744
            definitely_changed = kind != existing_ie.kind
725
745
            self._record_entry(path, file_id, specific_files, kind, name,
726
 
                parent_id, definitely_changed, existing_ie, report_changes)
 
746
                parent_id, definitely_changed, existing_ie, report_changes,
 
747
                content_summary)
727
748
 
728
749
        # Unversion IDs that were found to be deleted
729
750
        self.work_tree.unversion(deleted_ids)
742
763
            sub_tree.branch.repository = \
743
764
                self.work_tree.branch.repository
744
765
        try:
745
 
            sub_tree.commit(message=None, revprops=self.revprops,
 
766
            return sub_tree.commit(message=None, revprops=self.revprops,
746
767
                recursive=self.recursive,
747
768
                message_callback=self.message_callback,
748
769
                timestamp=self.timestamp, timezone=self.timezone,
751
772
                strict=self.strict, verbose=self.verbose,
752
773
                local=self.local, reporter=self.reporter)
753
774
        except errors.PointlessCommit:
754
 
            pass
 
775
            return self.work_tree.get_reference_revision(file_id)
755
776
 
756
777
    def _record_entry(self, path, file_id, specific_files, kind, name,
757
 
            parent_id, definitely_changed, existing_ie=None,
758
 
            report_changes=True):
 
778
        parent_id, definitely_changed, existing_ie, report_changes,
 
779
        content_summary):
759
780
        "Record the new inventory entry for a path if any."
760
781
        # mutter('check %s {%s}', path, file_id)
761
782
        # mutter('%s selected for commit', path)
764
785
        else:
765
786
            ie = existing_ie.copy()
766
787
            ie.revision = None
767
 
        if self.builder.record_entry_contents(ie, self.parent_invs, 
768
 
            path, self.work_tree):
 
788
        delta, version_recorded = self.builder.record_entry_contents(ie,
 
789
            self.parent_invs, path, self.work_tree, content_summary)
 
790
        if version_recorded:
769
791
            self.any_entries_changed = True
770
792
        if report_changes:
771
793
            self._report_change(ie, path)