/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/git/tree.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-11-16 18:59:44 UTC
  • mfrom: (7143.15.15 more-cleanups)
  • Revision ID: breezy.the.bot@gmail.com-20181116185944-biefv1sub37qfybm
Sprinkle some PEP8iness.

Merged from https://code.launchpad.net/~jelmer/brz/more-cleanups/+merge/358611

Show diffs side-by-side

added added

removed removed

Lines of Context:
135
135
                self.executable == other.executable)
136
136
 
137
137
    def __repr__(self):
138
 
        return "%s(file_id=%r, name=%r, parent_id=%r, text_size=%r, text_sha1=%r, executable=%r)" % (
 
138
        return ("%s(file_id=%r, name=%r, parent_id=%r, text_size=%r, "
 
139
                "text_sha1=%r, executable=%r)") % (
139
140
            type(self).__name__, self.file_id, self.name, self.parent_id,
140
141
            self.text_size, self.text_sha1, self.executable)
141
142
 
142
143
    def copy(self):
143
144
        ret = self.__class__(
144
 
                self.file_id, self.name, self.parent_id)
 
145
            self.file_id, self.name, self.parent_id)
145
146
        ret.text_sha1 = self.text_sha1
146
147
        ret.text_size = self.text_size
147
148
        ret.executable = self.executable
185
186
 
186
187
    def copy(self):
187
188
        return self.__class__(
188
 
                self.file_id, self.name, self.parent_id,
189
 
                self.symlink_target)
 
189
            self.file_id, self.name, self.parent_id,
 
190
            self.symlink_target)
190
191
 
191
192
 
192
193
class GitTreeSubmodule(_mod_tree.TreeLink):
204
205
        return 'tree-reference'
205
206
 
206
207
    def __repr__(self):
207
 
        return "%s(file_id=%r, name=%r, parent_id=%r, reference_revision=%r)" % (
 
208
        return ("%s(file_id=%r, name=%r, parent_id=%r, "
 
209
                "reference_revision=%r)") % (
208
210
            type(self).__name__, self.file_id, self.name, self.parent_id,
209
211
            self.reference_revision)
210
212
 
217
219
 
218
220
    def copy(self):
219
221
        return self.__class__(
220
 
                self.file_id, self.name, self.parent_id,
221
 
                self.reference_revision)
 
222
            self.file_id, self.name, self.parent_id,
 
223
            self.reference_revision)
222
224
 
223
225
 
224
226
entry_factory = {
254
256
        self.store = repository._git.object_store
255
257
        if not isinstance(revision_id, bytes):
256
258
            raise TypeError(revision_id)
257
 
        self.commit_id, self.mapping = repository.lookup_bzr_revision_id(revision_id)
 
259
        self.commit_id, self.mapping = repository.lookup_bzr_revision_id(
 
260
            revision_id)
258
261
        if revision_id == NULL_REVISION:
259
262
            self.tree = None
260
263
            self.mapping = default_mapping
267
270
            except KeyError:
268
271
                raise errors.NoSuchRevision(repository, revision_id)
269
272
            self.tree = commit.tree
270
 
            self._fileid_map = self.mapping.get_fileid_map(self.store.__getitem__, self.tree)
 
273
            self._fileid_map = self.mapping.get_fileid_map(
 
274
                self.store.__getitem__, self.tree)
271
275
 
272
276
    def _get_nested_repository(self, path):
273
277
        nested_repo_transport = self._repository.user_transport.clone(path)
274
 
        nested_controldir = _mod_controldir.ControlDir.open_from_transport(nested_repo_transport)
 
278
        nested_controldir = _mod_controldir.ControlDir.open_from_transport(
 
279
            nested_repo_transport)
275
280
        return nested_controldir.find_repository()
276
281
 
277
282
    def supports_rename_tracking(self):
283
288
            return NULL_REVISION
284
289
        (unused_path, commit_id) = change_scanner.find_last_change_revision(
285
290
            path.encode('utf-8'), self.commit_id)
286
 
        return self._repository.lookup_foreign_revision_id(commit_id, self.mapping)
 
291
        return self._repository.lookup_foreign_revision_id(
 
292
            commit_id, self.mapping)
287
293
 
288
294
    def get_file_mtime(self, path):
289
295
        try:
340
346
 
341
347
    def has_or_had_id(self, file_id):
342
348
        try:
343
 
            path = self.id2path(file_id)
 
349
            self.id2path(file_id)
344
350
        except errors.NoSuchId:
345
351
            return False
346
352
        return True
356
362
        if self.tree is None:
357
363
            raise errors.NoSuchFile(path)
358
364
        try:
359
 
            (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
360
 
                path.encode('utf-8'))
 
365
            (mode, hexsha) = tree_lookup_path(
 
366
                self.store.__getitem__, self.tree, path.encode('utf-8'))
361
367
        except KeyError:
362
368
            raise errors.NoSuchFile(self, path)
363
369
        else:
391
397
        if from_dir is None:
392
398
            from_dir = u""
393
399
        (store, mode, hexsha) = self._lookup_path(from_dir)
394
 
        if mode is None: # Root
 
400
        if mode is None:  # Root
395
401
            root_ie = self._get_dir_ie(b"", None)
396
402
        else:
397
403
            parent_path = posixpath.dirname(from_dir)
399
405
            if mode_kind(mode) == 'directory':
400
406
                root_ie = self._get_dir_ie(from_dir.encode("utf-8"), parent_id)
401
407
            else:
402
 
                root_ie = self._get_file_ie(store, from_dir.encode("utf-8"),
 
408
                root_ie = self._get_file_ie(
 
409
                    store, from_dir.encode("utf-8"),
403
410
                    posixpath.basename(from_dir), mode, hexsha)
404
411
        if include_root:
405
412
            yield (from_dir, "V", root_ie.kind, root_ie.file_id, root_ie)
406
413
        todo = []
407
414
        if root_ie.kind == 'directory':
408
 
            todo.append((store, from_dir.encode("utf-8"), b"", hexsha, root_ie.file_id))
 
415
            todo.append((store, from_dir.encode("utf-8"),
 
416
                         b"", hexsha, root_ie.file_id))
409
417
        while todo:
410
418
            (store, path, relpath, hexsha, parent_id) = todo.pop()
411
419
            tree = store[hexsha]
417
425
                if stat.S_ISDIR(mode):
418
426
                    ie = self._get_dir_ie(child_path, parent_id)
419
427
                    if recursive:
420
 
                        todo.append((store, child_path, child_relpath, hexsha, ie.file_id))
 
428
                        todo.append(
 
429
                            (store, child_path, child_relpath, hexsha,
 
430
                             ie.file_id))
421
431
                else:
422
 
                    ie = self._get_file_ie(store, child_path, name, mode, hexsha, parent_id)
423
 
                yield child_relpath.decode('utf-8'), "V", ie.kind, ie.file_id, ie
 
432
                    ie = self._get_file_ie(
 
433
                        store, child_path, name, mode, hexsha, parent_id)
 
434
                yield (child_relpath.decode('utf-8'), "V", ie.kind, ie.file_id,
 
435
                       ie)
424
436
 
425
437
    def _get_file_ie(self, store, path, name, mode, hexsha, parent_id):
426
438
        if not isinstance(path, bytes):
435
447
        if kind == 'symlink':
436
448
            ie.symlink_target = store[hexsha].data.decode('utf-8')
437
449
        elif kind == 'tree-reference':
438
 
            ie.reference_revision = self.mapping.revision_id_foreign_to_bzr(hexsha)
 
450
            ie.reference_revision = self.mapping.revision_id_foreign_to_bzr(
 
451
                hexsha)
439
452
        else:
440
453
            data = store[hexsha].data
441
454
            ie.text_sha1 = osutils.sha_string(data)
477
490
            if specific_files in ([""], []):
478
491
                specific_files = None
479
492
            else:
480
 
                specific_files = set([p.encode('utf-8') for p in specific_files])
 
493
                specific_files = set([p.encode('utf-8')
 
494
                                      for p in specific_files])
481
495
        todo = deque([(self.store, b"", self.tree, self.get_root_id())])
482
496
        if specific_files is None or u"" in specific_files:
483
497
            yield u"", self._get_dir_ie(b"", None)
492
506
                child_path_decoded = child_path.decode('utf-8')
493
507
                if stat.S_ISDIR(mode):
494
508
                    if (specific_files is None or
495
 
                        any(filter(lambda p: p.startswith(child_path), specific_files))):
 
509
                            any([p for p in specific_files if p.startswith(
 
510
                                child_path)])):
496
511
                        extradirs.append(
497
 
                            (store, child_path, hexsha, self.path2id(child_path_decoded)))
 
512
                            (store, child_path, hexsha,
 
513
                             self.path2id(child_path_decoded)))
498
514
                if specific_files is None or child_path in specific_files:
499
515
                    if stat.S_ISDIR(mode):
500
516
                        yield (child_path_decoded,
502
518
                    else:
503
519
                        yield (child_path_decoded,
504
520
                               self._get_file_ie(store, child_path, name, mode,
505
 
                                   hexsha, parent_id))
 
521
                                                 hexsha, parent_id))
506
522
            todo.extendleft(reversed(extradirs))
507
523
 
508
524
    def iter_references(self):
570
586
        if kind == 'file':
571
587
            executable = mode_is_executable(mode)
572
588
            contents = store[hexsha].data
573
 
            return (kind, len(contents), executable, osutils.sha_string(contents))
 
589
            return (kind, len(contents), executable,
 
590
                    osutils.sha_string(contents))
574
591
        elif kind == 'symlink':
575
592
            return (kind, None, None, store[hexsha].data.decode('utf-8'))
576
593
        elif kind == 'tree-reference':
581
598
            return (kind, None, None, None)
582
599
 
583
600
    def find_related_paths_across_trees(self, paths, trees=[],
584
 
            require_versioned=True):
 
601
                                        require_versioned=True):
585
602
        if paths is None:
586
603
            return None
587
604
        if require_versioned:
601
618
        if self.tree is None:
602
619
            return iter([])
603
620
        return self.store.iter_tree_contents(
604
 
                self.tree, include_trees=include_trees)
 
621
            self.tree, include_trees=include_trees)
605
622
 
606
623
    def annotate_iter(self, path, default_revision=CURRENT_REVISION):
607
624
        """Return an iterator of revision_id, line tuples.
629
646
 
630
647
    def walkdirs(self, prefix=u""):
631
648
        (store, mode, hexsha) = self._lookup_path(prefix)
632
 
        todo = deque([(store, prefix.encode('utf-8'), hexsha, self.path2id(prefix))])
 
649
        todo = deque(
 
650
            [(store, prefix.encode('utf-8'), hexsha, self.path2id(prefix))])
633
651
        while todo:
634
652
            store, path, tree_sha, parent_id = todo.popleft()
635
653
            path_decoded = path.decode('utf-8')
650
668
 
651
669
 
652
670
def tree_delta_from_git_changes(changes, mapping,
653
 
        fileid_maps, specific_files=None,
654
 
        require_versioned=False, include_root=False,
655
 
        target_extras=None):
 
671
                                fileid_maps, specific_files=None,
 
672
                                require_versioned=False, include_root=False,
 
673
                                target_extras=None):
656
674
    """Create a TreeDelta from two git trees.
657
675
 
658
676
    source and target are iterators over tuples with:
666
684
        if newpath == b'' and not include_root:
667
685
            continue
668
686
        if oldpath is None:
669
 
            oldpath_encoded = None
 
687
            oldpath_decoded = None
670
688
        else:
671
689
            oldpath_decoded = oldpath.decode('utf-8')
672
690
        if newpath is None:
674
692
        else:
675
693
            newpath_decoded = newpath.decode('utf-8')
676
694
        if not (specific_files is None or
677
 
                (oldpath is not None and osutils.is_inside_or_parent_of_any(specific_files, oldpath_decoded)) or
678
 
                (newpath is not None and osutils.is_inside_or_parent_of_any(specific_files, newpath_decoded))):
 
695
                (oldpath is not None and
 
696
                    osutils.is_inside_or_parent_of_any(
 
697
                        specific_files, oldpath_decoded)) or
 
698
                (newpath is not None and
 
699
                    osutils.is_inside_or_parent_of_any(
 
700
                        specific_files, newpath_decoded))):
679
701
            continue
680
702
        if mapping.is_special_file(oldpath):
681
703
            oldpath = None
686
708
        if oldpath is None:
687
709
            if newpath in target_extras:
688
710
                ret.unversioned.append(
689
 
                    (osutils.normalized_filename(newpath)[0], None, mode_kind(newmode)))
 
711
                    (osutils.normalized_filename(newpath)[0], None,
 
712
                     mode_kind(newmode)))
690
713
            else:
691
714
                file_id = new_fileid_map.lookup_file_id(newpath_decoded)
692
 
                ret.added.append((newpath_decoded, file_id, mode_kind(newmode)))
 
715
                ret.added.append(
 
716
                    (newpath_decoded, file_id, mode_kind(newmode)))
693
717
        elif newpath is None or newmode == 0:
694
718
            file_id = old_fileid_map.lookup_file_id(oldpath_decoded)
695
719
            ret.removed.append((oldpath_decoded, file_id, mode_kind(oldmode)))
697
721
            file_id = old_fileid_map.lookup_file_id(oldpath_decoded)
698
722
            ret.renamed.append(
699
723
                (oldpath_decoded, newpath.decode('utf-8'), file_id,
700
 
                mode_kind(newmode), (oldsha != newsha),
701
 
                (oldmode != newmode)))
 
724
                 mode_kind(newmode), (oldsha != newsha),
 
725
                 (oldmode != newmode)))
702
726
        elif mode_kind(oldmode) != mode_kind(newmode):
703
727
            file_id = new_fileid_map.lookup_file_id(newpath_decoded)
704
728
            ret.kind_changed.append(
705
729
                (newpath_decoded, file_id, mode_kind(oldmode),
706
 
                mode_kind(newmode)))
 
730
                 mode_kind(newmode)))
707
731
        elif oldsha != newsha or oldmode != newmode:
708
732
            if stat.S_ISDIR(oldmode) and stat.S_ISDIR(newmode):
709
733
                continue
710
734
            file_id = new_fileid_map.lookup_file_id(newpath_decoded)
711
735
            ret.modified.append(
712
736
                (newpath_decoded, file_id, mode_kind(newmode),
713
 
                (oldsha != newsha), (oldmode != newmode)))
 
737
                 (oldsha != newsha), (oldmode != newmode)))
714
738
        else:
715
739
            file_id = new_fileid_map.lookup_file_id(newpath_decoded)
716
 
            ret.unchanged.append((newpath_decoded, file_id, mode_kind(newmode)))
 
740
            ret.unchanged.append(
 
741
                (newpath_decoded, file_id, mode_kind(newmode)))
717
742
 
718
743
    return ret
719
744
 
720
745
 
721
 
def changes_from_git_changes(changes, mapping, specific_files=None, include_unchanged=False,
722
 
                             target_extras=None):
 
746
def changes_from_git_changes(changes, mapping, specific_files=None,
 
747
                             include_unchanged=False, target_extras=None):
723
748
    """Create a iter_changes-like generator from a git stream.
724
749
 
725
750
    source and target are iterators over tuples with:
737
762
        else:
738
763
            newpath_decoded = None
739
764
        if not (specific_files is None or
740
 
                (oldpath_decoded is not None and osutils.is_inside_or_parent_of_any(specific_files, oldpath_decoded)) or
741
 
                (newpath_decoded is not None and osutils.is_inside_or_parent_of_any(specific_files, newpath_decoded))):
 
765
                (oldpath_decoded is not None and
 
766
                    osutils.is_inside_or_parent_of_any(
 
767
                        specific_files, oldpath_decoded)) or
 
768
                (newpath_decoded is not None and
 
769
                    osutils.is_inside_or_parent_of_any(
 
770
                        specific_files, newpath_decoded))):
742
771
            continue
743
772
        if oldpath is not None and mapping.is_special_file(oldpath):
744
773
            continue
788
817
                newparent = mapping.generate_file_id(newparentpath)
789
818
        if (not include_unchanged and
790
819
            oldkind == 'directory' and newkind == 'directory' and
791
 
            oldpath_decoded == newpath_decoded):
 
820
                oldpath_decoded == newpath_decoded):
792
821
            continue
793
822
        yield (fileid, (oldpath_decoded, newpath_decoded), (oldsha != newsha),
794
 
             (oldversioned, newversioned),
795
 
             (oldparent, newparent), (oldname, newname),
796
 
             (oldkind, newkind), (oldexe, newexe))
 
823
               (oldversioned, newversioned),
 
824
               (oldparent, newparent), (oldname, newname),
 
825
               (oldkind, newkind), (oldexe, newexe))
797
826
 
798
827
 
799
828
class InterGitTrees(_mod_tree.InterTree):
813
842
                want_unversioned=False):
814
843
        with self.lock_read():
815
844
            changes, target_extras = self._iter_git_changes(
816
 
                    want_unchanged=want_unchanged,
817
 
                    require_versioned=require_versioned,
818
 
                    specific_files=specific_files,
819
 
                    extra_trees=extra_trees,
820
 
                    want_unversioned=want_unversioned)
 
845
                want_unchanged=want_unchanged,
 
846
                require_versioned=require_versioned,
 
847
                specific_files=specific_files,
 
848
                extra_trees=extra_trees,
 
849
                want_unversioned=want_unversioned)
821
850
            source_fileid_map = self.source._fileid_map
822
851
            target_fileid_map = self.target._fileid_map
823
 
            return tree_delta_from_git_changes(changes, self.target.mapping,
 
852
            return tree_delta_from_git_changes(
 
853
                changes, self.target.mapping,
824
854
                (source_fileid_map, target_fileid_map),
825
 
                specific_files=specific_files, include_root=include_root,
826
 
                target_extras=target_extras)
 
855
                specific_files=specific_files,
 
856
                include_root=include_root, target_extras=target_extras)
827
857
 
828
858
    def iter_changes(self, include_unchanged=False, specific_files=None,
829
859
                     pb=None, extra_trees=[], require_versioned=True,
830
860
                     want_unversioned=False):
831
861
        with self.lock_read():
832
862
            changes, target_extras = self._iter_git_changes(
833
 
                    want_unchanged=include_unchanged,
834
 
                    require_versioned=require_versioned,
835
 
                    specific_files=specific_files,
836
 
                    extra_trees=extra_trees,
837
 
                    want_unversioned=want_unversioned)
 
863
                want_unchanged=include_unchanged,
 
864
                require_versioned=require_versioned,
 
865
                specific_files=specific_files,
 
866
                extra_trees=extra_trees,
 
867
                want_unversioned=want_unversioned)
838
868
            return changes_from_git_changes(
839
 
                    changes, self.target.mapping,
840
 
                    specific_files=specific_files,
841
 
                    include_unchanged=include_unchanged,
842
 
                    target_extras=target_extras)
 
869
                changes, self.target.mapping,
 
870
                specific_files=specific_files,
 
871
                include_unchanged=include_unchanged,
 
872
                target_extras=target_extras)
843
873
 
844
874
    def _iter_git_changes(self, want_unchanged=False, specific_files=None,
845
 
            require_versioned=False, extra_trees=None,
846
 
            want_unversioned=False):
 
875
                          require_versioned=False, extra_trees=None,
 
876
                          want_unversioned=False):
847
877
        raise NotImplementedError(self._iter_git_changes)
848
878
 
849
879
 
860
890
                isinstance(target, GitRevisionTree))
861
891
 
862
892
    def _iter_git_changes(self, want_unchanged=False, specific_files=None,
863
 
            require_versioned=True, extra_trees=None,
864
 
            want_unversioned=False):
 
893
                          require_versioned=True, extra_trees=None,
 
894
                          want_unversioned=False):
865
895
        trees = [self.source]
866
896
        if extra_trees is not None:
867
897
            trees.extend(extra_trees)
868
898
        if specific_files is not None:
869
899
            specific_files = self.target.find_related_paths_across_trees(
870
 
                    specific_files, trees,
871
 
                    require_versioned=require_versioned)
 
900
                specific_files, trees,
 
901
                require_versioned=require_versioned)
872
902
 
873
 
        if self.source._repository._git.object_store != self.target._repository._git.object_store:
874
 
            store = OverlayObjectStore([self.source._repository._git.object_store,
875
 
                                        self.target._repository._git.object_store])
 
903
        if (self.source._repository._git.object_store !=
 
904
                self.target._repository._git.object_store):
 
905
            store = OverlayObjectStore(
 
906
                [self.source._repository._git.object_store,
 
907
                    self.target._repository._git.object_store])
876
908
        else:
877
909
            store = self.source._repository._git.object_store
878
 
        return self.source._repository._git.object_store.tree_changes(
 
910
        return store.tree_changes(
879
911
            self.source.tree, self.target.tree, want_unchanged=want_unchanged,
880
912
            include_trees=True, change_type_same=True), set()
881
913
 
927
959
        with self.lock_read():
928
960
            path = path.rstrip('/')
929
961
            if self.is_versioned(path.rstrip('/')):
930
 
                return self._fileid_map.lookup_file_id(osutils.safe_unicode(path))
 
962
                return self._fileid_map.lookup_file_id(
 
963
                    osutils.safe_unicode(path))
931
964
            return None
932
965
 
933
966
    def has_id(self, file_id):
990
1023
            try:
991
1024
                file, stat_val = self.get_file_with_stat(path)
992
1025
            except (errors.NoSuchFile, IOError):
993
 
                # TODO: Rather than come up with something here, use the old index
 
1026
                # TODO: Rather than come up with something here, use the old
 
1027
                # index
994
1028
                file = BytesIO()
995
1029
                stat_val = os.stat_result(
996
1030
                    (stat.S_IFREG | 0o644, 0, 0, 0, 0, 0, 0, 0, 0, 0))
997
1031
            with file:
998
1032
                blob.set_raw_string(file.read())
999
1033
            # Add object to the repository if it didn't exist yet
1000
 
            if not blob.id in self.store:
 
1034
            if blob.id not in self.store:
1001
1035
                self.store.add_object(blob)
1002
1036
            hexsha = blob.id
1003
1037
        elif kind == "symlink":
1012
1046
            blob.set_raw_string(
1013
1047
                self.get_symlink_target(path).encode("utf-8"))
1014
1048
            # Add object to the repository if it didn't exist yet
1015
 
            if not blob.id in self.store:
 
1049
            if blob.id not in self.store:
1016
1050
                self.store.add_object(blob)
1017
1051
            hexsha = blob.id
1018
1052
        elif kind == "tree-reference":
1019
1053
            if reference_revision is not None:
1020
 
                hexsha = self.branch.lookup_bzr_revision_id(reference_revision)[0]
 
1054
                hexsha = self.branch.lookup_bzr_revision_id(
 
1055
                    reference_revision)[0]
1021
1056
            else:
1022
1057
                hexsha = self._read_submodule_head(path)
1023
1058
                if hexsha is None:
1050
1085
                index = self.index
1051
1086
            for path, value in index.items():
1052
1087
                yield (posixpath.join(basepath, path), value)
1053
 
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
 
1088
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha,
 
1089
                 flags) = value
1054
1090
                if S_ISGITLINK(mode):
1055
 
                    pass # TODO(jelmer): dive into submodule
1056
 
 
 
1091
                    pass  # TODO(jelmer): dive into submodule
1057
1092
 
1058
1093
    def iter_entries_by_dir(self, specific_files=None, yield_parents=False):
1059
1094
        if yield_parents:
1072
1107
                if self.mapping.is_special_file(path):
1073
1108
                    continue
1074
1109
                path = path.decode("utf-8")
1075
 
                if specific_files is not None and not path in specific_files:
 
1110
                if specific_files is not None and path not in specific_files:
1076
1111
                    continue
1077
1112
                (parent, name) = posixpath.split(path)
1078
1113
                try:
1080
1115
                except errors.NoSuchFile:
1081
1116
                    continue
1082
1117
                if yield_parents or specific_files is None:
1083
 
                    for (dir_path, dir_ie) in self._add_missing_parent_ids(parent,
1084
 
                            dir_ids):
 
1118
                    for (dir_path, dir_ie) in self._add_missing_parent_ids(
 
1119
                            parent, dir_ids):
1085
1120
                        ret[(posixpath.dirname(dir_path), dir_path)] = dir_ie
1086
1121
                file_ie.parent_id = self.path2id(parent)
1087
1122
                ret[(posixpath.dirname(path), path)] = file_ie
1096
1131
    def _get_dir_ie(self, path, parent_id):
1097
1132
        file_id = self.path2id(path)
1098
1133
        return GitTreeDirectory(file_id,
1099
 
            posixpath.basename(path).strip("/"), parent_id)
 
1134
                                posixpath.basename(path).strip("/"), parent_id)
1100
1135
 
1101
1136
    def _get_file_ie(self, name, path, value, parent_id):
1102
1137
        if not isinstance(name, text_type):
1159
1194
            # A directory, perhaps?
1160
1195
            # TODO(jelmer): Deletes that involve submodules?
1161
1196
            for p in list(index):
1162
 
                if p.startswith(subpath+b"/"):
 
1197
                if p.startswith(subpath + b"/"):
1163
1198
                    count += 1
1164
1199
                    self._index_del_entry(index, p)
1165
1200
        else:
1182
1217
        # TODO(jelmer): This shouldn't be called, it's inventory specific.
1183
1218
        for (old_path, new_path, file_id, ie) in delta:
1184
1219
            if old_path is not None:
1185
 
                (index, old_subpath) = self._lookup_index(old_path.encode('utf-8'))
 
1220
                (index, old_subpath) = self._lookup_index(
 
1221
                    old_path.encode('utf-8'))
1186
1222
                if old_subpath in index:
1187
1223
                    self._index_del_entry(index, old_subpath)
1188
1224
                    self._versioned_dirs = None
1197
1233
            to_abs = self.abspath(to_dir)
1198
1234
            if not os.path.isdir(to_abs):
1199
1235
                raise errors.BzrMoveFailedError('', to_dir,
1200
 
                    errors.NotADirectory(to_abs))
 
1236
                                                errors.NotADirectory(to_abs))
1201
1237
 
1202
1238
            for from_rel in from_paths:
1203
1239
                from_tail = os.path.split(from_rel)[-1]
1222
1258
                    not self.is_versioned(to_rel))
1223
1259
            if after:
1224
1260
                if not self.has_filename(to_rel):
1225
 
                    raise errors.BzrMoveFailedError(from_rel, to_rel,
1226
 
                        errors.NoSuchFile(to_rel))
 
1261
                    raise errors.BzrMoveFailedError(
 
1262
                        from_rel, to_rel, errors.NoSuchFile(to_rel))
1227
1263
                if self.basis_tree().is_versioned(to_rel):
1228
 
                    raise errors.BzrMoveFailedError(from_rel, to_rel,
1229
 
                        errors.AlreadyVersionedError(to_rel))
 
1264
                    raise errors.BzrMoveFailedError(
 
1265
                        from_rel, to_rel, errors.AlreadyVersionedError(to_rel))
1230
1266
 
1231
1267
                kind = self.kind(to_rel)
1232
1268
            else:
1239
1275
                    exc_type = errors.BzrMoveFailedError
1240
1276
                if self.is_versioned(to_rel):
1241
1277
                    raise exc_type(from_rel, to_rel,
1242
 
                        errors.AlreadyVersionedError(to_rel))
 
1278
                                   errors.AlreadyVersionedError(to_rel))
1243
1279
                if not self.has_filename(from_rel):
1244
 
                    raise errors.BzrMoveFailedError(from_rel, to_rel,
1245
 
                        errors.NoSuchFile(from_rel))
 
1280
                    raise errors.BzrMoveFailedError(
 
1281
                        from_rel, to_rel, errors.NoSuchFile(from_rel))
1246
1282
                kind = self.kind(from_rel)
1247
1283
                if not self.is_versioned(from_rel) and kind != 'directory':
1248
1284
                    raise exc_type(from_rel, to_rel,
1249
 
                        errors.NotVersionedError(from_rel))
 
1285
                                   errors.NotVersionedError(from_rel))
1250
1286
                if self.has_filename(to_rel):
1251
1287
                    raise errors.RenameFailedFilesExist(
1252
1288
                        from_rel, to_rel, errors.FileExists(to_rel))
1257
1293
                (index, from_subpath) = self._lookup_index(from_path)
1258
1294
                if from_subpath not in index:
1259
1295
                    # It's not a file
1260
 
                    raise errors.BzrMoveFailedError(from_rel, to_rel,
 
1296
                    raise errors.BzrMoveFailedError(
 
1297
                        from_rel, to_rel,
1261
1298
                        errors.NotVersionedError(path=from_rel))
1262
1299
 
1263
1300
            if not after:
1265
1302
                    self._rename_one(from_rel, to_rel)
1266
1303
                except OSError as e:
1267
1304
                    if e.errno == errno.ENOENT:
1268
 
                        raise errors.BzrMoveFailedError(from_rel, to_rel,
1269
 
                            errors.NoSuchFile(to_rel))
 
1305
                        raise errors.BzrMoveFailedError(
 
1306
                            from_rel, to_rel, errors.NoSuchFile(to_rel))
1270
1307
                    raise
1271
1308
            if kind != 'directory':
1272
1309
                (index, from_index_path) = self._lookup_index(from_path)
1276
1313
                    pass
1277
1314
                self._index_add_entry(to_rel, kind)
1278
1315
            else:
1279
 
                todo = [(p, i) for (p, i) in self._recurse_index_entries() if p.startswith(from_path+b'/')]
 
1316
                todo = [(p, i) for (p, i) in self._recurse_index_entries()
 
1317
                        if p.startswith(from_path + b'/')]
1280
1318
                for child_path, child_value in todo:
1281
1319
                    (child_to_index, child_to_index_path) = self._lookup_index(
1282
 
                            posixpath.join(to_path, posixpath.relpath(child_path, from_path)))
 
1320
                        posixpath.join(to_path, posixpath.relpath(child_path, from_path)))
1283
1321
                    child_to_index[child_to_index_path] = child_value
1284
1322
                    # TODO(jelmer): Mark individual index as dirty
1285
1323
                    self._index_dirty = True
1286
 
                    (child_from_index, child_from_index_path) = self._lookup_index(child_path)
1287
 
                    self._index_del_entry(child_from_index, child_from_index_path)
 
1324
                    (child_from_index, child_from_index_path) = self._lookup_index(
 
1325
                        child_path)
 
1326
                    self._index_del_entry(
 
1327
                        child_from_index, child_from_index_path)
1288
1328
 
1289
1329
            self._versioned_dirs = None
1290
1330
            self.flush()
1291
1331
 
1292
1332
    def find_related_paths_across_trees(self, paths, trees=[],
1293
 
            require_versioned=True):
 
1333
                                        require_versioned=True):
1294
1334
        if paths is None:
1295
1335
            return None
1296
1336
 
1367
1407
                isinstance(target, MutableGitIndexTree))
1368
1408
 
1369
1409
    def _iter_git_changes(self, want_unchanged=False, specific_files=None,
1370
 
            require_versioned=False, extra_trees=None,
1371
 
            want_unversioned=False):
 
1410
                          require_versioned=False, extra_trees=None,
 
1411
                          want_unversioned=False):
1372
1412
        trees = [self.source]
1373
1413
        if extra_trees is not None:
1374
1414
            trees.extend(extra_trees)
1375
1415
        if specific_files is not None:
1376
1416
            specific_files = self.target.find_related_paths_across_trees(
1377
 
                    specific_files, trees,
1378
 
                    require_versioned=require_versioned)
 
1417
                specific_files, trees,
 
1418
                require_versioned=require_versioned)
1379
1419
        # TODO(jelmer): Restrict to specific_files, for performance reasons.
1380
1420
        with self.lock_read():
1381
1421
            return changes_between_git_tree_and_working_copy(
1388
1428
 
1389
1429
 
1390
1430
def changes_between_git_tree_and_working_copy(store, from_tree_sha, target,
1391
 
        want_unchanged=False, want_unversioned=False):
 
1431
                                              want_unchanged=False,
 
1432
                                              want_unversioned=False):
1392
1433
    """Determine the changes between a git tree and a working tree with index.
1393
1434
 
1394
1435
    """
1423
1464
            if stat.S_ISDIR(st.st_mode):
1424
1465
                blob = Tree()
1425
1466
            else:
1426
 
                blob = blob_from_path_and_stat(target.abspath(e).encode(osutils._fs_enc), st)
 
1467
                blob = blob_from_path_and_stat(
 
1468
                    target.abspath(e).encode(osutils._fs_enc), st)
1427
1469
            store.add_object(blob)
1428
1470
            np = np.encode('utf-8')
1429
1471
            blobs[np] = (blob.id, cleanup_mode(st.st_mode))
1430
1472
            extras.add(np)
1431
 
    to_tree_sha = commit_tree(store, dirified + [(p, s, m) for (p, (s, m)) in blobs.items()])
 
1473
    to_tree_sha = commit_tree(
 
1474
        store, dirified + [(p, s, m) for (p, (s, m)) in blobs.items()])
1432
1475
    return store.tree_changes(
1433
1476
        from_tree_sha, to_tree_sha, include_trees=True,
1434
1477
        want_unchanged=want_unchanged, change_type_same=True), extras