storageutil: extract filelog.cmp() to a standalone function
As part of implementing an alternate storage backend, I found myself
reimplementing this code.
With a little massaging, we can extract filelog.cmp() to a standalone
function.
As part of this, the call to revlog.cmp() was inlined (it is just a
2-line function).
I also tweaked some variable names to improve readability. I'll
further tweak names in a subsequent commit.
Differential Revision: https://phab.mercurial-scm.org/D4801
--- a/mercurial/filelog.py Fri Sep 28 11:37:49 2018 -0700
+++ b/mercurial/filelog.py Fri Sep 28 11:47:53 2018 -0700
@@ -135,26 +135,7 @@
returns True if text is different than what is stored.
"""
-
- t = text
- if text.startswith('\1\n'):
- t = '\1\n\1\n' + text
-
- samehashes = not self._revlog.cmp(node, t)
- if samehashes:
- return False
-
- # censored files compare against the empty file
- if self.iscensored(self.rev(node)):
- return text != ''
-
- # renaming a file produces a different hash, even if the data
- # remains unchanged. Check if it's the case (slow):
- if self.renamed(node):
- t2 = self.read(node)
- return t2 != text
-
- return True
+ return storageutil.filerevisiondifferent(self, node, text)
def verifyintegrity(self, state):
return self._revlog.verifyintegrity(state)
--- a/mercurial/utils/storageutil.py Fri Sep 28 11:37:49 2018 -0700
+++ b/mercurial/utils/storageutil.py Fri Sep 28 11:47:53 2018 -0700
@@ -108,6 +108,32 @@
return False
+def filerevisiondifferent(store, node, filedata):
+ """Determines whether file data is equivalent to a stored node."""
+
+ if filedata.startswith(b'\x01\n'):
+ revisiontext = b'\x01\n\x01\n' + filedata
+ else:
+ revisiontext = filedata
+
+ p1, p2 = store.parents(node)
+
+ computednode = hashrevisionsha1(revisiontext, p1, p2)
+
+ if computednode == node:
+ return False
+
+ # Censored files compare against the empty file.
+ if store.iscensored(store.rev(node)):
+ return filedata != b''
+
+ # Renaming a file produces a different hash, even if the data
+ # remains unchanged. Check if that's the case.
+ if store.renamed(node):
+ return store.read(node) != filedata
+
+ return True
+
def iterrevs(storelen, start=0, stop=None):
"""Iterate over revision numbers in a store."""
step = 1