/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/fastimport/bzr_commit_handler.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-06 01:18:08 UTC
  • mfrom: (7143 work)
  • mto: This revision was merged to the branch mainline in revision 7151.
  • Revision ID: jelmer@jelmer.uk-20181106011808-y870f4vq0ork3ahu
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
    return inv
56
56
 
57
57
 
58
 
class GenericCommitHandler(processor.CommitHandler):
 
58
class CommitHandler(processor.CommitHandler):
59
59
    """Base class for Bazaar CommitHandlers."""
60
60
 
61
61
    def __init__(self, command, cache_mgr, rev_store, verbose=False,
62
62
        prune_empty_dirs=True):
63
 
        super(GenericCommitHandler, self).__init__(command)
 
63
        super(CommitHandler, self).__init__(command)
64
64
        self.cache_mgr = cache_mgr
65
65
        self.rev_store = rev_store
66
66
        self.verbose = verbose
145
145
        # directory-path -> inventory-entry for current inventory
146
146
        self.directory_entries = {}
147
147
 
 
148
        self._dirs_that_might_become_empty = set()
 
149
 
 
150
        # A given file-id can only appear once so we accumulate
 
151
        # the entries in a dict then build the actual delta at the end
 
152
        self._delta_entries_by_fileid = {}
 
153
        if len(self.parents) == 0 or not self.rev_store.expects_rich_root():
 
154
            if self.parents:
 
155
                old_path = ''
 
156
            else:
 
157
                old_path = None
 
158
            # Need to explicitly add the root entry for the first revision
 
159
            # and for non rich-root inventories
 
160
            root_id = inventory.ROOT_ID
 
161
            root_ie = inventory.InventoryDirectory(root_id, u'', None)
 
162
            root_ie.revision = self.revision_id
 
163
            self._add_entry((old_path, '', root_id, root_ie))
 
164
 
148
165
    def _init_inventory(self):
149
166
        return self.rev_store.init_inventory(self.revision_id)
150
167
 
279
296
 
280
297
    def build_revision(self):
281
298
        rev_props = self._legal_revision_properties(self.command.properties)
282
 
        if 'branch-nick' not in rev_props:
283
 
            rev_props['branch-nick'] = self.cache_mgr.branch_mapper.git_to_bzr(
 
299
        if u'branch-nick' not in rev_props:
 
300
            rev_props[u'branch-nick'] = self.cache_mgr.branch_mapper.git_to_bzr(
284
301
                    self.branch_ref)
285
302
        self._save_author_info(rev_props)
286
303
        committer = self.command.committer
331
348
        else:
332
349
            return
333
350
        # If we reach here, there are authors worth storing
334
 
        rev_props['authors'] = "\n".join(author_ids)
 
351
        rev_props[u'authors'] = "\n".join(author_ids)
335
352
 
336
353
    def _modify_item(self, path, kind, is_executable, data, inv):
337
354
        """Add to or change an item in the inventory."""
363
380
            self.directory_entries[path] = ie
364
381
            # There are no lines stored for a directory so
365
382
            # make sure the cache used by get_lines knows that
366
 
            self.data_for_commit[file_id] = ''
 
383
            self.data_for_commit[file_id] = b''
367
384
        elif kind == 'symlink':
368
385
            ie.symlink_target = self._decode_path(data)
369
386
            # There are no lines stored for a symlink so
370
387
            # make sure the cache used by get_lines knows that
371
 
            self.data_for_commit[file_id] = ''
 
388
            self.data_for_commit[file_id] = b''
372
389
        else:
373
390
            self.warning("Cannot import items of kind '%s' yet - ignoring '%s'"
374
391
                % (kind, path))
413
430
        self.directory_entries[dirname] = ie
414
431
        # There are no lines stored for a directory so
415
432
        # make sure the cache used by get_lines knows that
416
 
        self.data_for_commit[dir_file_id] = ''
 
433
        self.data_for_commit[dir_file_id] = b''
417
434
 
418
435
        # It's possible that a file or symlink with that file-id
419
436
        # already exists. If it does, we need to delete it.
520
537
        # that means the loader then needs to know what the "new" text is.
521
538
        # We therefore must go back to the revision store to get it.
522
539
        lines = self.rev_store.get_file_lines(rev_id, file_id)
523
 
        self.data_for_commit[file_id] = ''.join(lines)
 
540
        self.data_for_commit[file_id] = b''.join(lines)
524
541
 
525
542
    def _delete_all_items(self, inv):
526
543
        if len(inv) == 0:
537
554
                return
538
555
        self.warning("ignoring delete of %s as not in parent inventories", path)
539
556
 
540
 
 
541
 
class InventoryCommitHandler(GenericCommitHandler):
542
 
    """A CommitHandler that builds and saves Inventory objects."""
543
 
 
544
 
    def pre_process_files(self):
545
 
        super(InventoryCommitHandler, self).pre_process_files()
546
 
 
547
 
        # Seed the inventory from the previous one. Note that
548
 
        # the parent class version of pre_process_files() has
549
 
        # already set the right basis_inventory for this branch
550
 
        # but we need to copy it in order to mutate it safely
551
 
        # without corrupting the cached inventory value.
552
 
        if len(self.parents) == 0:
553
 
            self.inventory = self.basis_inventory
554
 
        else:
555
 
            self.inventory = copy_inventory(self.basis_inventory)
556
 
        self.inventory_root = self.inventory.root
557
 
 
558
 
        # directory-path -> inventory-entry for current inventory
559
 
        self.directory_entries = dict(self.inventory.directories())
560
 
 
561
 
        # Initialise the inventory revision info as required
562
 
        if self.rev_store.expects_rich_root():
563
 
            self.inventory.revision_id = self.revision_id
564
 
        else:
565
 
            # In this revision store, root entries have no knit or weave.
566
 
            # When serializing out to disk and back in, root.revision is
567
 
            # always the new revision_id.
568
 
            self.inventory.root.revision = self.revision_id
569
 
 
570
 
    def post_process_files(self):
571
 
        """Save the revision."""
572
 
        self.cache_mgr.inventories[self.revision_id] = self.inventory
573
 
        self.rev_store.load(self.revision, self.inventory, None,
574
 
            lambda file_id: self._get_data(file_id),
575
 
            lambda file_id: self._get_per_file_parents(file_id),
576
 
            lambda revision_ids: self._get_inventories(revision_ids))
577
 
 
578
 
    def record_new(self, path, ie):
579
 
        try:
580
 
            # If this is a merge, the file was most likely added already.
581
 
            # The per-file parent(s) must therefore be calculated and
582
 
            # we can't assume there are none.
583
 
            per_file_parents, ie.revision = \
584
 
                self.rev_store.get_parents_and_revision_for_entry(ie)
585
 
            self.per_file_parents_for_commit[ie.file_id] = per_file_parents
586
 
            self.inventory.add(ie)
587
 
        except errors.DuplicateFileId:
588
 
            # Directory already exists as a file or symlink
589
 
            del self.inventory[ie.file_id]
590
 
            # Try again
591
 
            self.inventory.add(ie)
592
 
 
593
 
    def record_changed(self, path, ie, parent_id):
594
 
        # HACK: no API for this (del+add does more than it needs to)
595
 
        per_file_parents, ie.revision = \
596
 
            self.rev_store.get_parents_and_revision_for_entry(ie)
597
 
        self.per_file_parents_for_commit[ie.file_id] = per_file_parents
598
 
        self.inventory._byid[ie.file_id] = ie
599
 
        parent_ie = self.inventory._byid[parent_id]
600
 
        parent_ie.children[ie.name] = ie
601
 
 
602
 
    def record_delete(self, path, ie):
603
 
        self.inventory.remove_recursive_id(ie.file_id)
604
 
 
605
 
    def record_rename(self, old_path, new_path, file_id, ie):
606
 
        # For a rename, the revision-id is always the new one so
607
 
        # no need to change/set it here
608
 
        ie.revision = self.revision_id
609
 
        per_file_parents, _ = \
610
 
            self.rev_store.get_parents_and_revision_for_entry(ie)
611
 
        self.per_file_parents_for_commit[file_id] = per_file_parents
612
 
        new_basename, new_parent_id = self._ensure_directory(new_path,
613
 
            self.inventory)
614
 
        self.inventory.rename(file_id, new_parent_id, new_basename)
615
 
 
616
 
    def modify_handler(self, filecmd):
617
 
        if filecmd.dataref is not None:
618
 
            data = self.cache_mgr.fetch_blob(filecmd.dataref)
619
 
        else:
620
 
            data = filecmd.data
621
 
        self.debug("modifying %s", filecmd.path)
622
 
        (kind, is_executable) = mode_to_kind(filecmd.mode)
623
 
        self._modify_item(self._decode_path(filecmd.path), kind,
624
 
            is_executable, data, self.inventory)
625
 
 
626
 
    def delete_handler(self, filecmd):
627
 
        self.debug("deleting %s", filecmd.path)
628
 
        self._delete_item(self._decode_path(filecmd.path), self.inventory)
629
 
 
630
 
    def copy_handler(self, filecmd):
631
 
        src_path = self._decode_path(filecmd.src_path)
632
 
        dest_path = self._decode_path(filecmd.dest_path)
633
 
        self.debug("copying %s to %s", src_path, dest_path)
634
 
        self._copy_item(src_path, dest_path, self.inventory)
635
 
 
636
 
    def rename_handler(self, filecmd):
637
 
        old_path = self._decode_path(filecmd.old_path)
638
 
        new_path = self._decode_path(filecmd.new_path)
639
 
        self.debug("renaming %s to %s", old_path, new_path)
640
 
        self._rename_item(old_path, new_path, self.inventory)
641
 
 
642
 
    def deleteall_handler(self, filecmd):
643
 
        self.debug("deleting all files (and also all directories)")
644
 
        self._delete_all_items(self.inventory)
645
 
 
646
 
 
647
 
class InventoryDeltaCommitHandler(GenericCommitHandler):
648
 
    """A CommitHandler that builds Inventories by applying a delta."""
649
 
 
650
 
    def pre_process_files(self):
651
 
        super(InventoryDeltaCommitHandler, self).pre_process_files()
652
 
        self._dirs_that_might_become_empty = set()
653
 
 
654
 
        # A given file-id can only appear once so we accumulate
655
 
        # the entries in a dict then build the actual delta at the end
656
 
        self._delta_entries_by_fileid = {}
657
 
        if len(self.parents) == 0 or not self.rev_store.expects_rich_root():
658
 
            if self.parents:
659
 
                old_path = ''
660
 
            else:
661
 
                old_path = None
662
 
            # Need to explicitly add the root entry for the first revision
663
 
            # and for non rich-root inventories
664
 
            root_id = inventory.ROOT_ID
665
 
            root_ie = inventory.InventoryDirectory(root_id, u'', None)
666
 
            root_ie.revision = self.revision_id
667
 
            self._add_entry((old_path, '', root_id, root_ie))
668
 
 
669
557
    def post_process_files(self):
670
558
        """Save the revision."""
671
559
        delta = self._get_final_delta()
730
618
            # used. However, it is cheaper than having to create a full copy of
731
619
            # the inventory for every commit.
732
620
            new_inv = self.basis_inventory.create_by_apply_delta(delta,
733
 
                'not-a-valid-revision-id:')
 
621
                b'not-a-valid-revision-id:')
734
622
        else:
735
623
            new_inv = inventory.Inventory(revision_id=self.revision_id)
736
624
            # This is set in the delta so remove it to prevent a duplicate
833
721
                del self.directory_entries[path]
834
722
            except KeyError:
835
723
                pass
836
 
            for child_relpath, entry in \
837
 
                self.basis_inventory.iter_entries_by_dir(from_dir=ie):
838
 
                child_path = osutils.pathjoin(path, child_relpath)
839
 
                self._add_entry((child_path, None, entry.file_id, None))
840
 
                self._paths_deleted_this_commit.add(child_path)
841
 
                if entry.kind == 'directory':
842
 
                    try:
843
 
                        del self.directory_entries[child_path]
844
 
                    except KeyError:
845
 
                        pass
 
724
            if self.basis_inventory.get_entry(ie.file_id).kind == 'directory':
 
725
                for child_relpath, entry in \
 
726
                    self.basis_inventory.iter_entries_by_dir(from_dir=ie.file_id):
 
727
                    child_path = osutils.pathjoin(path, child_relpath)
 
728
                    self._add_entry((child_path, None, entry.file_id, None))
 
729
                    self._paths_deleted_this_commit.add(child_path)
 
730
                    if entry.kind == 'directory':
 
731
                        try:
 
732
                            del self.directory_entries[child_path]
 
733
                        except KeyError:
 
734
                            pass
846
735
 
847
736
    def record_rename(self, old_path, new_path, file_id, old_ie):
848
737
        new_ie = old_ie.copy()