Mercurial > public > mercurial-scm > hg
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 |