def tree_items(oid, tree_data, names=frozenset(), bupm=None): def tree_item(ent_oid, kind, gitmode): if kind == BUP_CHUNKED: meta = Metadata.read(bupm) if bupm else default_file_mode return Chunky(oid=ent_oid, meta=meta) if S_ISDIR(gitmode): # No metadata here (accessable via '.' inside ent_oid). return Item(meta=default_dir_mode, oid=ent_oid) return Item(oid=ent_oid, meta=(Metadata.read(bupm) if bupm \ else _default_mode_for_gitmode(gitmode))) assert len(oid) == 20 if not names: dot_meta = _read_dir_meta(bupm) if bupm else default_dir_mode yield '.', Item(oid=oid, meta=dot_meta) tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == '.bupm': continue assert name != '.' yield name, tree_item(ent_oid, kind, gitmode) return # Assumes the tree is properly formed, i.e. there are no # duplicates, and entries will be in git tree order. if type(names) not in (frozenset, set): names = frozenset(names) remaining = len(names) # Account for the bupm sort order issue (cf. ordered_tree_entries above) last_name = max(names) if bupm else max(names) + '/' if '.' in names: dot_meta = _read_dir_meta(bupm) if bupm else default_dir_mode yield '.', Item(oid=oid, meta=dot_meta) if remaining == 1: return remaining -= 1 tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == '.bupm': continue assert name != '.' if name not in names: if name > last_name: break # given bupm sort order, we're finished if (kind == BUP_CHUNKED or not S_ISDIR(gitmode)) and bupm: Metadata.read(bupm) continue yield name, tree_item(ent_oid, kind, gitmode) if remaining == 1: break remaining -= 1
def tree_item(ent_oid, kind, gitmode): if kind == BUP_CHUNKED: meta = Metadata.read(bupm) if bupm else default_file_mode return Chunky(oid=ent_oid, meta=meta) if S_ISDIR(gitmode): # No metadata here (accessable via '.' inside ent_oid). return Item(meta=default_dir_mode, oid=ent_oid) return Item(oid=ent_oid, meta=(Metadata.read(bupm) if bupm \ else _default_mode_for_gitmode(gitmode)))
def _tree_items(oid, tree_data, names=frozenset(), bupm=None): def tree_item(ent_oid, kind, gitmode): if kind == BUP_CHUNKED: meta = Metadata.read(bupm) if bupm else default_file_mode return Chunky(oid=ent_oid, meta=meta) if S_ISDIR(gitmode): # No metadata here (accessable via '.' inside ent_oid). return Item(meta=default_dir_mode, oid=ent_oid) meta = Metadata.read(bupm) if bupm else None # handle the case of metadata being empty/missing in bupm # (or there not being bupm at all) if meta is None: meta = _default_mode_for_gitmode(gitmode) return Item(oid=ent_oid, meta=meta) assert len(oid) == 20 if not names: tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == b'.bupm': continue assert name != b'.' yield name, tree_item(ent_oid, kind, gitmode) return # Assumes the tree is properly formed, i.e. there are no # duplicates, and entries will be in git tree order. if type(names) not in (frozenset, set): names = frozenset(names) remaining = len(names) # Account for the bupm sort order issue (cf. ordered_tree_entries above) last_name = max(names) if bupm else max(names) + b'/' tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == b'.bupm': continue assert name != b'.' if name not in names: if name > last_name: break # given bupm sort order, we're finished if (kind == BUP_CHUNKED or not S_ISDIR(gitmode)) and bupm: Metadata.read(bupm) continue yield name, tree_item(ent_oid, kind, gitmode) if remaining == 1: break remaining -= 1
def tree_item(ent_oid, kind, gitmode): if kind == BUP_CHUNKED: meta = Metadata.read(bupm) if bupm else default_file_mode return Chunky(oid=ent_oid, meta=meta) if S_ISDIR(gitmode): # No metadata here (accessable via '.' inside ent_oid). return Item(meta=default_dir_mode, oid=ent_oid) meta = Metadata.read(bupm) if bupm else None # handle the case of metadata being empty/missing in bupm # (or there not being bupm at all) if meta is None: meta = _default_mode_for_gitmode(gitmode) return Item(oid=ent_oid, meta=meta)
def tree_items(repo, oid): """Yield (name, entry_oid, meta) for each entry in oid. meta will be a Metadata object for any non-directories and for '.', otherwise None. """ # This is a simpler approach than the one in the vfs, used to # cross-check its behavior. tree_data, bupm_oid = vfs.tree_data_and_bupm(repo, oid) bupm = vfs._FileReader(repo, bupm_oid) if bupm_oid else None try: maybe_meta = lambda: Metadata.read(bupm) if bupm else None m = maybe_meta() if m: m.size = 0 yield TreeDictValue(name='.', oid=oid, meta=m) tree_ents = vfs.ordered_tree_entries(tree_data, bupm=True) for name, mangled_name, kind, gitmode, sub_oid in tree_ents: if mangled_name == '.bupm': continue assert name != '.' if S_ISDIR(gitmode): if kind == BUP_CHUNKED: yield TreeDictValue(name=name, oid=sub_oid, meta=maybe_meta()) else: yield TreeDictValue(name=name, oid=sub_oid, meta=vfs.default_dir_mode) else: yield TreeDictValue(name=name, oid=sub_oid, meta=maybe_meta()) finally: if bupm: bupm.close()
def tree_items(repo, oid): """Yield (name, entry_oid, meta) for each entry in oid. meta will be a Metadata object for any non-directories and for '.', otherwise None. """ # This is a simpler approach than the one in the vfs, used to # cross-check its behavior. tree_data, bupm_oid = vfs.tree_data_and_bupm(repo, oid) bupm = vfs._FileReader(repo, bupm_oid) if bupm_oid else None try: maybe_meta = lambda : Metadata.read(bupm) if bupm else None m = maybe_meta() if m and m.size is None: m.size = 0 yield TreeDictValue(name='.', oid=oid, meta=m) tree_ents = vfs.ordered_tree_entries(tree_data, bupm=True) for name, mangled_name, kind, gitmode, sub_oid in tree_ents: if mangled_name == '.bupm': continue assert name != '.' if S_ISDIR(gitmode): if kind == BUP_CHUNKED: yield TreeDictValue(name=name, oid=sub_oid, meta=maybe_meta()) else: yield TreeDictValue(name=name, oid=sub_oid, meta=vfs.default_dir_mode) else: yield TreeDictValue(name=name, oid=sub_oid, meta=maybe_meta()) finally: if bupm: bupm.close()
def _read_dir_meta(bupm): # This is because save writes unmodified Metadata() entries for # fake parents -- test-save-strip-graft.sh demonstrates. m = Metadata.read(bupm) if not m: return default_dir_mode assert m.mode is not None if m.size is None: m.size = 0 return m
def read_m(port, has_meta): if has_meta: m = Metadata.read(port) return m return read_vuint(port)
def tree_items(oid, tree_data, names=frozenset(tuple()), bupm=None): def tree_item(ent_oid, kind, gitmode): if kind == BUP_CHUNKED: meta = Metadata.read(bupm) if bupm else default_file_mode return Chunky(oid=ent_oid, meta=meta) if S_ISDIR(gitmode): # No metadata here (accessable via '.' inside ent_oid). return Item(meta=default_dir_mode, oid=ent_oid) return Item(oid=ent_oid, meta=(Metadata.read(bupm) if bupm \ else _default_mode_for_gitmode(gitmode))) assert len(oid) == 20 if not names: dot_meta = _read_dir_meta(bupm) if bupm else default_dir_mode yield '.', Item(oid=oid, meta=dot_meta) tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == '.bupm': continue assert name != '.' yield name, tree_item(ent_oid, kind, gitmode) return # Assumes the tree is properly formed, i.e. there are no # duplicates, and entries will be in git tree order. if type(names) not in (frozenset, set): names = frozenset(names) remaining = len(names) # Account for the bupm sort order issue (cf. ordered_tree_entries above) last_name = max(names) if bupm else max(names) + '/' if '.' in names: dot_meta = _read_dir_meta(bupm) if bupm else default_dir_mode yield '.', Item(oid=oid, meta=dot_meta) if remaining == 1: return remaining -= 1 tree_entries = ordered_tree_entries(tree_data, bupm) for name, mangled_name, kind, gitmode, ent_oid in tree_entries: if mangled_name == '.bupm': continue assert name != '.' if name not in names: if bupm: if (name + '/') > last_name: break # given git sort order, we're finished else: if name > last_name: break # given bupm sort order, we're finished if (kind == BUP_CHUNKED or not S_ISDIR(gitmode)) and bupm: Metadata.read(bupm) continue yield name, tree_item(ent_oid, kind, gitmode) if remaining == 1: break remaining -= 1