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 |