As part of implementing an alternate storage backend, I found myself
reinventing this wheel.
Let's create a utility function for doing the work.
| hg-reviewers |
As part of implementing an alternate storage backend, I found myself
reinventing this wheel.
Let's create a utility function for doing the work.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/filelog.py (10 lines) | |||
| M | mercurial/utils/storageutil.py (19 lines) |
| return storageutil.filtermetadata(self.revision(node)) | return storageutil.filtermetadata(self.revision(node)) | ||||
| def add(self, text, meta, transaction, link, p1=None, p2=None): | def add(self, text, meta, transaction, link, p1=None, p2=None): | ||||
| if meta or text.startswith('\1\n'): | if meta or text.startswith('\1\n'): | ||||
| text = storageutil.packmeta(meta, text) | text = storageutil.packmeta(meta, text) | ||||
| return self.addrevision(text, transaction, link, p1, p2) | return self.addrevision(text, transaction, link, p1, p2) | ||||
| def renamed(self, node): | def renamed(self, node): | ||||
| if self.parents(node)[0] != revlog.nullid: | return storageutil.filerevisioncopied(self, node) | ||||
| return False | |||||
| t = self.revision(node) | |||||
| m = storageutil.parsemeta(t)[0] | |||||
| # copy and copyrev occur in pairs. In rare cases due to bugs, | |||||
| # one can occur without the other. | |||||
| if m and "copy" in m and "copyrev" in m: | |||||
| return (m["copy"], revlog.bin(m["copyrev"])) | |||||
| return False | |||||
| def size(self, rev): | def size(self, rev): | ||||
| """return the size of a given revision""" | """return the size of a given revision""" | ||||
| # for revisions with renames, we have to go the slow way | # for revisions with renames, we have to go the slow way | ||||
| node = self.node(rev) | node = self.node(rev) | ||||
| if self.renamed(node): | if self.renamed(node): | ||||
| return len(self.read(node)) | return len(self.read(node)) | ||||
| a new buffer without hte metadata. | a new buffer without hte metadata. | ||||
| """ | """ | ||||
| if not text.startswith(b'\x01\n'): | if not text.startswith(b'\x01\n'): | ||||
| return text | return text | ||||
| offset = text.index(b'\x01\n', 2) | offset = text.index(b'\x01\n', 2) | ||||
| return text[offset + 2:] | return text[offset + 2:] | ||||
| def filerevisioncopied(store, node): | |||||
| """Resolve file revision copy metadata. | |||||
| Returns ``False`` if the file has no copy metadata. Otherwise a | |||||
| 2-tuple of the source filename and node. | |||||
| """ | |||||
| if store.parents(node)[0] != nullid: | |||||
| return False | |||||
| meta = parsemeta(store.revision(node))[0] | |||||
| # copy and copyrev occur in pairs. In rare cases due to old bugs, | |||||
| # one can occur without the other. So ensure both are present to flag | |||||
| # as a copy. | |||||
| if meta and b'copy' in meta and b'copyrev' in meta: | |||||
| return meta[b'copy'], bin(meta[b'copyrev']) | |||||
| return False | |||||
| def iterrevs(storelen, start=0, stop=None): | def iterrevs(storelen, start=0, stop=None): | ||||
| """Iterate over revision numbers in a store.""" | """Iterate over revision numbers in a store.""" | ||||
| step = 1 | step = 1 | ||||
| if stop is not None: | if stop is not None: | ||||
| if start > stop: | if start > stop: | ||||
| step = -1 | step = -1 | ||||
| stop += step | stop += step | ||||