418
420
yield self._get_file_ie(child_path, name, mode, hexsha,
421
def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
423
def iter_entries_by_dir(self, specific_files=None, yield_parents=False):
422
424
if self.tree is None:
424
426
if yield_parents:
425
427
# TODO(jelmer): Support yield parents
426
428
raise NotImplementedError
427
if specific_file_ids is not None:
428
specific_paths = [self.id2path(file_id).encode('utf-8') for file_id in specific_file_ids]
429
if specific_paths in ([""], []):
430
specific_paths = None
429
if specific_files is not None:
430
if specific_files in ([""], []):
431
specific_files = None
432
specific_paths = set(specific_paths)
434
specific_paths = None
433
specific_files = set([p.encode('utf-8') for p in specific_files])
435
434
todo = set([("", self.tree, None)])
437
436
path, tree_sha, parent_id = todo.pop()
438
437
ie = self._get_dir_ie(path, parent_id)
439
if specific_paths is None or path in specific_paths:
438
if specific_files is None or path in specific_files:
440
439
yield path.decode("utf-8"), ie
441
440
tree = self.store[tree_sha]
442
441
for name, mode, hexsha in tree.iteritems():
445
444
child_path = posixpath.join(path, name)
446
445
if stat.S_ISDIR(mode):
447
if (specific_paths is None or
448
any(filter(lambda p: p.startswith(child_path), specific_paths))):
446
if (specific_files is None or
447
any(filter(lambda p: p.startswith(child_path), specific_files))):
449
448
todo.add((child_path, hexsha, ie.file_id))
450
elif specific_paths is None or child_path in specific_paths:
449
elif specific_files is None or child_path in specific_files:
451
450
yield (child_path.decode("utf-8"),
452
451
self._get_file_ie(child_path, name, mode, hexsha,
508
507
return (kind, None, None, None)
509
def find_related_paths_across_trees(self, paths, trees=[],
510
require_versioned=True):
513
if require_versioned:
514
trees = [self] + (trees if trees is not None else [])
518
if t.is_versioned(p):
523
raise errors.PathsNotVersionedError(unversioned)
524
return filter(self.is_versioned, paths)
511
527
def tree_delta_from_git_changes(changes, mapping,
512
528
(old_fileid_map, new_fileid_map), specific_files=None,
641
657
want_unversioned=False):
642
658
changes = self._iter_git_changes(want_unchanged=want_unchanged,
643
659
require_versioned=require_versioned,
644
specific_files=specific_files)
660
specific_files=specific_files,
661
extra_trees=extra_trees)
645
662
source_fileid_map = self.source._fileid_map
646
663
target_fileid_map = self.target._fileid_map
647
664
return tree_delta_from_git_changes(changes, self.target.mapping,
653
670
want_unversioned=False):
654
671
changes = self._iter_git_changes(want_unchanged=include_unchanged,
655
672
require_versioned=require_versioned,
656
specific_files=specific_files)
673
specific_files=specific_files,
674
extra_trees=extra_trees)
657
675
return changes_from_git_changes(changes, self.target.mapping,
658
676
specific_files=specific_files, include_unchanged=include_unchanged)
660
def _iter_git_changes(self, want_unchanged=False):
678
def _iter_git_changes(self, want_unchanged=False, specific_files=None,
679
require_versioned=False, extra_trees=None):
661
680
raise NotImplementedError(self._iter_git_changes)
673
692
return (isinstance(source, GitRevisionTree) and
674
693
isinstance(target, GitRevisionTree))
676
def _iter_git_changes(self, want_unchanged=False, require_versioned=False,
677
specific_files=None):
678
if require_versioned and specific_files:
679
for path in specific_files:
680
if (not self.source.is_versioned(path) and
681
not self.target.is_versioned(path)):
682
raise errors.PathsNotVersionedError(path)
695
def _iter_git_changes(self, want_unchanged=False, specific_files=None,
696
require_versioned=True, extra_trees=None):
697
trees = [self.source]
698
if extra_trees is not None:
699
trees.extend(extra_trees)
700
if specific_files is not None:
701
specific_files = self.target.find_related_paths_across_trees(
702
specific_files, trees,
703
require_versioned=require_versioned)
684
705
if self.source._repository._git.object_store != self.target._repository._git.object_store:
685
706
store = OverlayObjectStore([self.source._repository._git.object_store,
816
837
if self._versioned_dirs is not None:
817
838
self._ensure_versioned_dir(encoded_path)
819
def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
840
def iter_entries_by_dir(self, specific_files=None, yield_parents=False):
820
841
if yield_parents:
821
842
raise NotImplementedError(self.iter_entries_by_dir)
822
843
with self.lock_read():
823
if specific_file_ids is not None:
825
for file_id in specific_file_ids:
829
specific_paths.append(self.id2path(file_id))
830
except errors.NoSuchId:
832
specific_paths = set(specific_paths)
844
if specific_files is not None:
845
specific_files = set(specific_files)
834
specific_paths = None
847
specific_files = None
835
848
root_ie = self._get_dir_ie(u"", None)
837
if specific_paths is None or u"" in specific_paths:
850
if specific_files is None or u"" in specific_files:
838
851
ret[(None, u"")] = root_ie
839
852
dir_ids = {u"": root_ie.file_id}
840
853
for path, value in self.index.iteritems():
841
854
if self.mapping.is_special_file(path):
843
856
path = path.decode("utf-8")
844
if specific_paths is not None and not path in specific_paths:
857
if specific_files is not None and not path in specific_files:
846
859
(parent, name) = posixpath.split(path)
848
861
file_ie = self._get_file_ie(name, path, value, None)
849
862
except errors.NoSuchFile:
851
if yield_parents or specific_file_ids is None:
864
if yield_parents or specific_files is None:
852
865
for (dir_path, dir_ie) in self._add_missing_parent_ids(parent,
854
867
ret[(posixpath.dirname(dir_path), dir_path)] = dir_ie
1039
1052
self._versioned_dirs = None
1055
def find_related_paths_across_trees(self, paths, trees=[],
1056
require_versioned=True):
1060
if require_versioned:
1061
trees = [self] + (trees if trees is not None else [])
1065
if t.is_versioned(p):
1070
raise errors.PathsNotVersionedError(unversioned)
1072
return filter(self.is_versioned, paths)