comparison mercurial/context.py @ 30361:1070df141718

dirstate: change added/modified placeholder hash length to 20 bytes Previously the added/modified placeholder hash for manifests generated from the dirstate was a 21byte long string consisting of the p1 file hash plus a single character to indicate an add or a modify. Normal hashes are only 20 bytes long. This makes it complicated to implement more efficient manifest implementations which rely on the hashes being fixed length. Let's change this hash to just be 20 bytes long, and rely on the astronomical improbability of an actual hash being these 20 bytes (just like we rely on no hash every being the nullid). This changes the possible behavior slightly in that the hash for all added/modified entries in the dirstate manifest will now be the same (so simple node comparisons would say they are equal), but we should never be doing simple node comparisons on these nodes even with the old hashes, because they did not accurately represent the content (i.e. two files based off the same p1 file node, with different working copy contents would have the same hash (even with the appended character) in the old scheme too, so we couldn't depend on the hashes period).
author Durham Goode <durham@fb.com>
date Thu, 10 Nov 2016 02:19:16 -0800
parents 0298a07f64d9
children 73ce055b169a
comparison
equal deleted inserted replaced
30360:0298a07f64d9 30361:1070df141718
12 import re 12 import re
13 import stat 13 import stat
14 14
15 from .i18n import _ 15 from .i18n import _
16 from .node import ( 16 from .node import (
17 addednodeid,
17 bin, 18 bin,
18 hex, 19 hex,
20 modifiednodeid,
19 newnodeid, 21 newnodeid,
20 nullid, 22 nullid,
21 nullrev, 23 nullrev,
22 short, 24 short,
23 wdirid, 25 wdirid,
1230 an extra 'a'. This is used by manifests merge to see that files 1232 an extra 'a'. This is used by manifests merge to see that files
1231 are different and by update logic to avoid deleting newly added files. 1233 are different and by update logic to avoid deleting newly added files.
1232 """ 1234 """
1233 parents = self.parents() 1235 parents = self.parents()
1234 1236
1235 man1 = parents[0].manifest() 1237 man = parents[0].manifest().copy()
1236 man = man1.copy() 1238
1237 if len(parents) > 1:
1238 man2 = self.p2().manifest()
1239 def getman(f):
1240 if f in man1:
1241 return man1
1242 return man2
1243 else:
1244 getman = lambda f: man1
1245
1246 copied = self._repo.dirstate.copies()
1247 ff = self._flagfunc 1239 ff = self._flagfunc
1248 for i, l in (("a", self._status.added), ("m", self._status.modified)): 1240 for i, l in ((addednodeid, self._status.added),
1241 (modifiednodeid, self._status.modified)):
1249 for f in l: 1242 for f in l:
1250 orig = copied.get(f, f) 1243 man[f] = i
1251 man[f] = getman(orig).get(orig, nullid) + i
1252 try: 1244 try:
1253 man.setflag(f, ff(f)) 1245 man.setflag(f, ff(f))
1254 except OSError: 1246 except OSError:
1255 pass 1247 pass
1256 1248