def test_symlink_detect_changes(self): left = inventory.InventoryLink('123', 'hello.c', ROOT_ID) left.text_sha1 = 123 left.executable = True left.symlink_target='foo' right = inventory.InventoryLink('123', 'hello.c', ROOT_ID) right.text_sha1 = 321 right.symlink_target='foo' self.assertEqual((False, False), left.detect_changes(right)) self.assertEqual((False, False), right.detect_changes(left)) left.symlink_target = 'different' self.assertEqual((True, False), left.detect_changes(right)) self.assertEqual((True, False), right.detect_changes(left))
def _unpack_entry(self, elt): kind = elt.tag if not InventoryEntry.versionable_kind(kind): raise AssertionError('unsupported entry kind %s' % kind) get_cached = _get_utf8_or_ascii parent_id = elt.get('parent_id') if parent_id is not None: parent_id = get_cached(parent_id) file_id = get_cached(elt.get('file_id')) if kind == 'directory': ie = inventory.InventoryDirectory(file_id, elt.get('name'), parent_id) elif kind == 'file': ie = inventory.InventoryFile(file_id, elt.get('name'), parent_id) ie.text_sha1 = elt.get('text_sha1') if elt.get('executable') == 'yes': ie.executable = True v = elt.get('text_size') ie.text_size = v and int(v) elif kind == 'symlink': ie = inventory.InventoryLink(file_id, elt.get('name'), parent_id) ie.symlink_target = elt.get('symlink_target') else: raise errors.UnsupportedInventoryKind(kind) revision = elt.get('revision') if revision is not None: revision = get_cached(revision) ie.revision = revision return ie
def _unpack_entry(self, elt): ## original format inventories don't have a parent_id for ## nodes in the root directory, but it's cleaner to use one ## internally. parent_id = elt.get('parent_id') if parent_id is None: parent_id = ROOT_ID kind = elt.get('kind') if kind == 'directory': ie = inventory.InventoryDirectory(elt.get('file_id'), elt.get('name'), parent_id) elif kind == 'file': ie = inventory.InventoryFile(elt.get('file_id'), elt.get('name'), parent_id) ie.text_id = elt.get('text_id') ie.text_sha1 = elt.get('text_sha1') v = elt.get('text_size') ie.text_size = v and int(v) elif kind == 'symlink': ie = inventory.InventoryLink(elt.get('file_id'), elt.get('name'), parent_id) ie.symlink_target = elt.get('symlink_target') else: raise BzrError("unknown kind %r" % kind) ## mutter("read inventoryentry: %r", elt.attrib) return ie
def get_sample_inventory(self): inv = Inventory('tree-root-321', revision_id='rev_outer') inv.add(inventory.InventoryFile('file-id', 'file', 'tree-root-321')) inv.add(inventory.InventoryDirectory('dir-id', 'dir', 'tree-root-321')) inv.add(inventory.InventoryLink('link-id', 'link', 'tree-root-321')) inv['tree-root-321'].revision = 'rev_outer' inv['dir-id'].revision = 'rev_outer' inv['file-id'].revision = 'rev_outer' inv['file-id'].text_sha1 = 'A' inv['file-id'].text_size = 1 inv['link-id'].revision = 'rev_outer' inv['link-id'].symlink_target = 'a' return inv
def _build_inventory(self, tree_id, ie, path): assert isinstance(path, str) tree = self._repository._git.tree(tree_id) for mode, name, hexsha in tree.entries(): basename = name.decode("utf-8") if path == "": child_path = name else: child_path = urlutils.join(path, name) file_id = self.mapping.generate_file_id(child_path) entry_kind = (mode & 0700000) / 0100000 if entry_kind == 0: child_ie = inventory.InventoryDirectory( file_id, basename, ie.file_id) elif entry_kind == 1: file_kind = (mode & 070000) / 010000 b = self._repository._git.get_blob(hexsha) if file_kind == 0: child_ie = inventory.InventoryFile(file_id, basename, ie.file_id) child_ie.text_sha1 = osutils.sha_string(b.data) elif file_kind == 2: child_ie = inventory.InventoryLink(file_id, basename, ie.file_id) child_ie.text_sha1 = osutils.sha_string("") else: raise AssertionError("Unknown file kind, perms=%o." % (mode, )) child_ie.text_id = b.id child_ie.text_size = len(b.data) else: raise AssertionError("Unknown blob kind, perms=%r." % (mode, )) fs_mode = mode & 0777 child_ie.executable = bool(fs_mode & 0111) child_ie.revision = self.revision_id self._inventory.add(child_ie) if entry_kind == 0: self._build_inventory(hexsha, child_ie, child_path)
def test_link_has_text(self): link = inventory.InventoryLink('123', 'hello.c', ROOT_ID) self.failIf(link.has_text())
def test_link_kind_character(self): dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID) self.assertEqual(dir.kind_character(), '')
def unpack_inventory_entry(elt, entry_cache=None, return_from_cache=False): elt_get = elt.get file_id = elt_get('file_id') revision = elt_get('revision') # Check and see if we have already unpacked this exact entry # Some timings for "repo.revision_trees(last_100_revs)" # bzr mysql # unmodified 4.1s 40.8s # using lru 3.5s # using fifo 2.83s 29.1s # lru._cache 2.8s # dict 2.75s 26.8s # inv.add 2.5s 26.0s # no_copy 2.00s 20.5s # no_c,dict 1.95s 18.0s # Note that a cache of 10k nodes is more than sufficient to hold all of # the inventory for the last 100 revs for bzr, but not for mysql (20k # is enough for mysql, which saves the same 2s as using a dict) # Breakdown of mysql using time.clock() # 4.1s 2 calls to element.get for file_id, revision_id # 4.5s cache_hit lookup # 7.1s InventoryFile.copy() # 2.4s InventoryDirectory.copy() # 0.4s decoding unique entries # 1.6s decoding entries after FIFO fills up # 0.8s Adding nodes to FIFO (including flushes) # 0.1s cache miss lookups # Using an LRU cache # 4.1s 2 calls to element.get for file_id, revision_id # 9.9s cache_hit lookup # 10.8s InventoryEntry.copy() # 0.3s cache miss lookus # 1.2s decoding entries # 1.0s adding nodes to LRU if entry_cache is not None and revision is not None: key = (file_id, revision) try: # We copy it, because some operations may mutate it cached_ie = entry_cache[key] except KeyError: pass else: # Only copying directory entries drops us 2.85s => 2.35s if return_from_cache: if cached_ie.kind == 'directory': return cached_ie.copy() return cached_ie return cached_ie.copy() kind = elt.tag if not inventory.InventoryEntry.versionable_kind(kind): raise AssertionError('unsupported entry kind %s' % kind) file_id = get_utf8_or_ascii(file_id) if revision is not None: revision = get_utf8_or_ascii(revision) parent_id = elt_get('parent_id') if parent_id is not None: parent_id = get_utf8_or_ascii(parent_id) if kind == 'directory': ie = inventory.InventoryDirectory(file_id, elt_get('name'), parent_id) elif kind == 'file': ie = inventory.InventoryFile(file_id, elt_get('name'), parent_id) ie.text_sha1 = elt_get('text_sha1') if elt_get('executable') == 'yes': ie.executable = True v = elt_get('text_size') ie.text_size = v and int(v) elif kind == 'symlink': ie = inventory.InventoryLink(file_id, elt_get('name'), parent_id) ie.symlink_target = elt_get('symlink_target') elif kind == 'tree-reference': file_id = elt.attrib['file_id'] name = elt.attrib['name'] parent_id = elt.attrib['parent_id'] revision = elt.get('revision') reference_revision = elt.get('reference_revision') ie = inventory.TreeReference(file_id, name, parent_id, revision, reference_revision) else: raise errors.UnsupportedInventoryKind(kind) ie.revision = revision if revision is not None and entry_cache is not None: # We cache a copy() because callers like to mutate objects, and # that would cause the item in cache to mutate as well. # This has a small effect on many-inventory performance, because # the majority fraction is spent in cache hits, not misses. entry_cache[key] = ie.copy() return ie