~ian-clatworthy/bzr-fastimport/inconsistent-delta-fixes

« back to all changes in this revision

Viewing changes to bzr_commit_handler.py

  • Committer: Ian Clatworthy
  • Date: 2009-08-22 04:16:30 UTC
  • Revision ID: ian.clatworthy@canonical.com-20090822041630-1upnufpomqvvmb8j
handle a delete of a newly added file

Show diffs side-by-side

added added

removed removed

Lines of Context:
323
323
        return result
324
324
 
325
325
    def _delete_item(self, path, inv):
326
 
        file_id = inv.path2id(path)
327
 
        if file_id is None:
328
 
            self.mutter("ignoring delete of %s as not in inventory", path)
329
 
            return
330
 
        try:
331
 
            ie = inv[file_id]
332
 
        except errors.NoSuchId:
333
 
            self.mutter("ignoring delete of %s as not in inventory", path)
 
326
        newly_added = self._new_file_ids.get(path)
 
327
        if newly_added:
 
328
            # We've only just added this path earlier in this commit.
 
329
            file_id = newly_added
 
330
            # note: delta entries look like (old, new, file-id, ie)
 
331
            ie = self._delta_entries_by_fileid[file_id][3]
334
332
        else:
335
 
            self.record_delete(path, ie)
 
333
            file_id = inv.path2id(path)
 
334
            if file_id is None:
 
335
                self.mutter("ignoring delete of %s as not in inventory", path)
 
336
                return
 
337
            try:
 
338
                ie = inv[file_id]
 
339
            except errors.NoSuchId:
 
340
                self.mutter("ignoring delete of %s as not in inventory", path)
 
341
                return
 
342
        self.record_delete(path, ie)
336
343
 
337
344
    def _copy_item(self, src_path, dest_path, inv):
338
345
        if not self.parents:
543
550
        if self.prune_empty_dirs and self._dirs_that_might_become_empty:
544
551
            candidates = osutils.minimum_path_selection(
545
552
                self._dirs_that_might_become_empty)
 
553
            never_born = set()
546
554
            for path, file_id in self._empty_after_delta(delta, candidates):
547
 
                delta.append((path, None, file_id, None))
548
 
        #print "delta:\n%s\n\n" % "\n".join([str(de) for de in delta])
 
555
                newly_added = self._new_file_ids.get(path)
 
556
                if newly_added:
 
557
                    never_born.add(newly_added)
 
558
                else:
 
559
                    delta.append((path, None, file_id, None))
 
560
            # Clean up entries that got deleted before they were ever added
 
561
            if never_born:
 
562
                delta = [de for de in delta if de[2] not in never_born]
549
563
        return delta
550
564
 
551
565
    def _empty_after_delta(self, delta, candidates):
552
 
        new_inv = self.basis_inventory._get_mutable_inventory()
553
 
        new_inv.apply_delta(delta)
 
566
        #self.mutter("delta so far is:\n%s" % "\n".join([str(de) for de in delta]))
 
567
        #self.mutter("candidates for deletion are:\n%s" % "\n".join([c for c in candidates]))
 
568
        new_inv = self._get_proposed_inventory(delta)
554
569
        result = []
555
570
        for dir in candidates:
556
571
            file_id = new_inv.path2id(dir)
579
594
                        self.note("pruning empty directory parent %s" % (dir,))
580
595
        return result
581
596
 
 
597
    def _get_proposed_inventory(self, delta):
 
598
        if len(self.parents):
 
599
            new_inv = self.basis_inventory._get_mutable_inventory()
 
600
            new_inv.apply_delta(delta)
 
601
        else:
 
602
            new_inv = inventory.Inventory(revision_id=self.revision_id)
 
603
            # This is set in the delta so remove it to prevent a duplicate
 
604
            del new_inv[inventory.ROOT_ID]
 
605
            new_inv.apply_delta(delta)
 
606
        return new_inv
 
607
 
582
608
    def _add_entry(self, entry):
583
609
        # We need to combine the data if multiple entries have the same file-id.
584
610
        # For example, a rename followed by a modification looks like:
608
634
        if new_path is None and old_path is None:
609
635
            # This is a delete cancelling a previous add
610
636
            del self._delta_entries_by_fileid[file_id]
 
637
            parent_dir = osutils.dirname(existing[1])
 
638
            self.mutter("cancelling add of %s with parent %s" % (existing[1], parent_dir))
 
639
            if parent_dir:
 
640
                self._dirs_that_might_become_empty.add(parent_dir)
611
641
            return
612
642
        else:
613
643
            self._delta_entries_by_fileid[file_id] = entry