/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: 2019-06-02 02:35:46 UTC
  • mfrom: (7309 work)
  • mto: This revision was merged to the branch mainline in revision 7319.
  • Revision ID: jelmer@jelmer.uk-20190602023546-lqco868tnv26d8ow
merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from ... import (
21
21
    debug,
22
22
    errors,
23
 
    generate_ids,
24
23
    osutils,
25
24
    revision,
26
25
    )
27
26
from ...bzr import (
 
27
    generate_ids,
28
28
    inventory,
29
29
    serializer,
30
30
    )
44
44
 
45
45
 
46
46
_serializer_handles_escaping = hasattr(serializer.Serializer,
47
 
    'squashes_xml_invalid_characters')
 
47
                                       'squashes_xml_invalid_characters')
48
48
 
49
49
 
50
50
def copy_inventory(inv):
59
59
    """Base class for Bazaar CommitHandlers."""
60
60
 
61
61
    def __init__(self, command, cache_mgr, rev_store, verbose=False,
62
 
        prune_empty_dirs=True):
 
62
                 prune_empty_dirs=True):
63
63
        super(CommitHandler, self).__init__(command)
64
64
        self.cache_mgr = cache_mgr
65
65
        self.rev_store = rev_store
106
106
        self.revision_id = self.gen_revision_id()
107
107
        # cache of texts for this commit, indexed by file-id
108
108
        self.data_for_commit = {}
109
 
        #if self.rev_store.expects_rich_root():
 
109
        # if self.rev_store.expects_rich_root():
110
110
        self.data_for_commit[inventory.ROOT_ID] = []
111
111
 
112
112
        # Track the heads and get the real parent list
115
115
        # Convert the parent commit-ids to bzr revision-ids
116
116
        if parents:
117
117
            self.parents = [self.cache_mgr.lookup_committish(p)
118
 
                for p in parents]
 
118
                            for p in parents]
119
119
        else:
120
120
            self.parents = []
121
121
        self.debug("%s id: %s, parents: %s", self.command.id,
122
 
            self.revision_id, str(self.parents))
 
122
                   self.revision_id, str(self.parents))
123
123
 
124
124
        # Tell the RevisionStore we're starting a new commit
125
125
        self.revision = self.build_revision()
126
126
        self.parent_invs = [self.get_inventory(p) for p in self.parents]
127
127
        self.rev_store.start_new_revision(self.revision, self.parents,
128
 
            self.parent_invs)
 
128
                                          self.parent_invs)
129
129
 
130
130
        # cache of per-file parents for this commit, indexed by file-id
131
131
        self.per_file_parents_for_commit = {}
191
191
 
192
192
    def _get_inventories(self, revision_ids):
193
193
        """Get the inventories for revision-ids.
194
 
        
 
194
 
195
195
        This is a callback used by the RepositoryStore to
196
196
        speed up inventory reconstruction.
197
197
        """
218
218
 
219
219
    def bzr_file_id_and_new(self, path):
220
220
        """Get a Bazaar file identifier and new flag for a path.
221
 
        
 
221
 
222
222
        :return: file_id, is_new where
223
223
          is_new = True if the file_id is newly created
224
224
        """
232
232
            id = self.basis_inventory.path2id(path)
233
233
            if id is not None:
234
234
                return id, False
235
 
            
 
235
 
236
236
            # Try the other inventories
237
237
            if len(self.parents) > 1:
238
238
                for inv in self.parent_invs[1:]:
244
244
        dirname, basename = osutils.split(path)
245
245
        id = generate_ids.gen_file_id(basename)
246
246
        self.debug("Generated new file id %s for '%s' in revision-id '%s'",
247
 
            id, path, self.revision_id)
 
247
                   id, path, self.revision_id)
248
248
        self._new_file_ids[path] = id
249
249
        return id, True
250
250
 
259
259
            # The spec says fields are *typically* utf8 encoded
260
260
            # but that isn't enforced by git-fast-export (at least)
261
261
            self.warning("%s not in utf8 - replacing unknown "
262
 
                "characters" % (field,))
 
262
                         "characters" % (field,))
263
263
            return value.decode('utf-8', 'replace')
264
264
 
265
265
    def _decode_path(self, path):
269
269
            # The spec says fields are *typically* utf8 encoded
270
270
            # but that isn't enforced by git-fast-export (at least)
271
271
            self.warning("path %r not in utf8 - replacing unknown "
272
 
                "characters" % (path,))
 
272
                         "characters" % (path,))
273
273
            return path.decode('utf-8', 'replace')
274
274
 
275
275
    def _format_name_email(self, section, name, email):
298
298
        rev_props = self._legal_revision_properties(self.command.properties)
299
299
        if u'branch-nick' not in rev_props:
300
300
            rev_props[u'branch-nick'] = self.cache_mgr.branch_mapper.git_to_bzr(
301
 
                    self.branch_ref)
 
301
                self.branch_ref)
302
302
        self._save_author_info(rev_props)
303
303
        committer = self.command.committer
304
304
        who = self._format_name_email("committer", committer[0], committer[1])
313
313
            # We need to assume the bad ol' days
314
314
            message = helpers.escape_commit_message(message)
315
315
        return revision.Revision(
316
 
           timestamp=committer[2],
317
 
           timezone=committer[3],
318
 
           committer=who,
319
 
           message=message,
320
 
           revision_id=self.revision_id,
321
 
           properties=rev_props,
322
 
           parent_ids=self.parents)
 
316
            timestamp=committer[2],
 
317
            timezone=committer[3],
 
318
            committer=who,
 
319
            message=message,
 
320
            revision_id=self.revision_id,
 
321
            properties=rev_props,
 
322
            parent_ids=self.parents)
323
323
 
324
324
    def _legal_revision_properties(self, props):
325
325
        """Clean-up any revision properties we can't handle."""
342
342
            return
343
343
        if self.command.more_authors:
344
344
            authors = [author] + self.command.more_authors
345
 
            author_ids = [self._format_name_email("author", a[0], a[1]) for a in authors]
 
345
            author_ids = [self._format_name_email(
 
346
                "author", a[0], a[1]) for a in authors]
346
347
        elif author != self.command.committer:
347
 
            author_ids = [self._format_name_email("author", author[0], author[1])]
 
348
            author_ids = [self._format_name_email(
 
349
                "author", author[0], author[1])]
348
350
        else:
349
351
            return
350
352
        # If we reach here, there are authors worth storing
362
364
            # to be created already by a previous rename
363
365
            if kind != 'directory':
364
366
                self.warning("%s already added in this commit - ignoring" %
365
 
                    (path,))
 
367
                             (path,))
366
368
            return
367
369
 
368
370
        # Create the new InventoryEntry
388
390
            self.data_for_commit[file_id] = b''
389
391
        else:
390
392
            self.warning("Cannot import items of kind '%s' yet - ignoring '%s'"
391
 
                % (kind, path))
 
393
                         % (kind, path))
392
394
            return
393
395
        # Record it
394
396
        try:
397
399
            try:
398
400
                self.record_new(path, ie)
399
401
            except:
400
 
                print("failed to add path '%s' with entry '%s' in command %s" \
401
 
                    % (path, ie, self.command.id))
402
 
                print("parent's children are:\n%r\n" % (ie.parent_id.children,))
 
402
                print("failed to add path '%s' with entry '%s' in command %s"
 
403
                      % (path, ie, self.command.id))
 
404
                print("parent's children are:\n%r\n" %
 
405
                      (ie.parent_id.children,))
403
406
                raise
404
407
        else:
405
408
            if old_ie.kind == 'directory':
425
428
        dir_basename, parent_id = self._ensure_directory(dirname, inv)
426
429
        dir_file_id = self.bzr_file_id(dirname)
427
430
        ie = inventory.entry_factory['directory'](dir_file_id,
428
 
            dir_basename, parent_id)
 
431
                                                  dir_basename, parent_id)
429
432
        ie.revision = self.revision_id
430
433
        self.directory_entries[dirname] = ie
431
434
        # There are no lines stored for a directory so
441
444
 
442
445
    def _get_directory_entry(self, inv, dirname):
443
446
        """Get the inventory entry for a directory.
444
 
        
 
447
 
445
448
        Raises KeyError if dirname is not a directory in inv.
446
449
        """
447
450
        result = self.directory_entries.get(dirname)
494
497
            file_id = inv.path2id(src_path)
495
498
            if file_id is None:
496
499
                self.warning("ignoring copy of %s to %s - source does not exist",
497
 
                    src_path, dest_path)
 
500
                             src_path, dest_path)
498
501
                return
499
502
            ie = inv.get_entry(file_id)
500
503
        kind = ie.kind
502
505
            if newly_changed:
503
506
                content = self.data_for_commit[file_id]
504
507
            else:
505
 
                content = self.rev_store.get_file_text(self.parents[0], file_id)
 
508
                content = self.rev_store.get_file_text(
 
509
                    self.parents[0], file_id)
506
510
            self._modify_item(dest_path, kind, ie.executable, content, inv)
507
511
        elif kind == 'symlink':
508
512
            self._modify_item(dest_path, kind, False,
509
 
                ie.symlink_target.encode("utf-8"), inv)
 
513
                              ie.symlink_target.encode("utf-8"), inv)
510
514
        else:
511
515
            self.warning("ignoring copy of %s %s - feature not yet supported",
512
 
                kind, dest_path)
 
516
                         kind, dest_path)
513
517
 
514
518
    def _rename_item(self, old_path, new_path, inv):
515
519
        existing = self._new_file_ids.get(old_path) or \
552
556
        for parent in self.parents[1:]:
553
557
            if fileid in self.get_inventory(parent):
554
558
                return
555
 
        self.warning("ignoring delete of %s as not in parent inventories", path)
 
559
        self.warning(
 
560
            "ignoring delete of %s as not in parent inventories", path)
556
561
 
557
562
    def post_process_files(self):
558
563
        """Save the revision."""
559
564
        delta = self._get_final_delta()
560
565
        inv = self.rev_store.load_using_delta(self.revision,
561
 
            self.basis_inventory, delta, None,
562
 
            self._get_data,
563
 
            self._get_per_file_parents,
564
 
            self._get_inventories)
 
566
                                              self.basis_inventory, delta, None,
 
567
                                              self._get_data,
 
568
                                              self._get_per_file_parents,
 
569
                                              self._get_inventories)
565
570
        self.cache_mgr.inventories[self.revision_id] = inv
566
 
        #print "committed %s" % self.revision_id
 
571
        # print "committed %s" % self.revision_id
567
572
 
568
573
    def _get_final_delta(self):
569
574
        """Generate the final delta.
618
623
            # used. However, it is cheaper than having to create a full copy of
619
624
            # the inventory for every commit.
620
625
            new_inv = self.basis_inventory.create_by_apply_delta(delta,
621
 
                b'not-a-valid-revision-id:')
 
626
                                                                 b'not-a-valid-revision-id:')
622
627
        else:
623
628
            new_inv = inventory.Inventory(revision_id=self.revision_id)
624
629
            # This is set in the delta so remove it to prevent a duplicate
626
631
            try:
627
632
                new_inv.apply_delta(delta)
628
633
            except errors.InconsistentDelta:
629
 
                self.mutter("INCONSISTENT DELTA IS:\n%s" % "\n".join([str(de) for de in delta]))
 
634
                self.mutter("INCONSISTENT DELTA IS:\n%s" %
 
635
                            "\n".join([str(de) for de in delta]))
630
636
                raise
631
637
        return new_inv
632
638
 
660
666
            # This is a delete cancelling a previous add
661
667
            del self._delta_entries_by_fileid[file_id]
662
668
            parent_dir = osutils.dirname(existing[1])
663
 
            self.mutter("cancelling add of %s with parent %s" % (existing[1], parent_dir))
 
669
            self.mutter("cancelling add of %s with parent %s" %
 
670
                        (existing[1], parent_dir))
664
671
            if parent_dir:
665
672
                self._dirs_that_might_become_empty.add(parent_dir)
666
673
            return
723
730
                pass
724
731
            if self.basis_inventory.get_entry(ie.file_id).kind == 'directory':
725
732
                for child_relpath, entry in \
726
 
                    self.basis_inventory.iter_entries_by_dir(from_dir=ie.file_id):
 
733
                        self.basis_inventory.iter_entries_by_dir(from_dir=ie.file_id):
727
734
                    child_path = osutils.pathjoin(path, child_relpath)
728
735
                    self._add_entry((child_path, None, entry.file_id, None))
729
736
                    self._paths_deleted_this_commit.add(child_path)
736
743
    def record_rename(self, old_path, new_path, file_id, old_ie):
737
744
        new_ie = old_ie.copy()
738
745
        new_basename, new_parent_id = self._ensure_directory(new_path,
739
 
            self.basis_inventory)
 
746
                                                             self.basis_inventory)
740
747
        new_ie.name = new_basename
741
748
        new_ie.parent_id = new_parent_id
742
749
        new_ie.revision = self.revision_id
765
772
        # Create the new InventoryEntry
766
773
        kind = old_ie.kind
767
774
        basename, parent_id = self._ensure_directory(new_path,
768
 
            self.basis_inventory)
 
775
                                                     self.basis_inventory)
769
776
        ie = inventory.make_entry(kind, basename, parent_id, file_id)
770
777
        ie.revision = self.revision_id
771
778
        if kind == 'file':
792
799
        self.debug("modifying %s", filecmd.path)
793
800
        decoded_path = self._decode_path(filecmd.path)
794
801
        self._modify_item(decoded_path, kind,
795
 
            executable, data, self.basis_inventory)
 
802
                          executable, data, self.basis_inventory)
796
803
 
797
804
    def delete_handler(self, filecmd):
798
805
        self.debug("deleting %s", filecmd.path)