tags: behave better if a tags cache entry is partially written
This is done by discarding any partial cache entry, instead of
filling the partial cache entry with 0xff before.
Differential Revision: https://phab.mercurial-scm.org/D8095
--- a/mercurial/tags.py Fri Feb 07 15:55:26 2020 -0500
+++ b/mercurial/tags.py Fri Feb 07 16:01:32 2020 -0500
@@ -720,15 +720,18 @@
self._dirtyoffset = None
- if rawlen < wantedlen:
- self._dirtyoffset = rawlen
- self._raw.extend(b'\xff' * (wantedlen - rawlen))
- elif rawlen > wantedlen:
+ rawlentokeep = min(wantedlen, (rawlen / _fnodesrecsize) * _fnodesrecsize)
+ if rawlen > rawlentokeep:
# There's no easy way to truncate array instances. This seems
# slightly less evil than copying a potentially large array slice.
- for i in range(rawlen - wantedlen):
+ for i in range(rawlen - rawlentokeep):
self._raw.pop()
- self._dirtyoffset = len(self._raw)
+ rawlen = len(self._raw)
+ self._dirtyoffset = rawlen
+ if rawlen < wantedlen:
+ if self._dirtyoffset is None:
+ self._dirtyoffset = rawlen
+ self._raw.extend(b'\xff' * (wantedlen - rawlen))
def getfnode(self, node, computemissing=True):
"""Obtain the filenode of the .hgtags file at a specified revision.
--- a/tests/test-tags.t Fri Feb 07 15:55:26 2020 -0500
+++ b/tests/test-tags.t Fri Feb 07 16:01:32 2020 -0500
@@ -371,25 +371,19 @@
1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags exited 0 after * seconds (glob)
1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> blackbox -l 6
-Junk data + missing cache entries results in hg further corrupting the
-cache, then failing.
+On junk data + missing cache entries, hg also overwrites the junk.
$ rm -f .hg/cache/tags2-visible
$ truncate .hg/cache/hgtagsfnodes1 -s -10
$ hg debugtagscache | tail -2
4 0c192d7d5e6b78a714de54a2e9627952a877e25a 0c04f2a8af31de17fab7422878ee5a2dadbc943d
- 5 8dbfe60eff306a54259cfe007db9e330e7ecf866 0c04f2a8af31de17fab7ffffffffffffffffffff
+ 5 8dbfe60eff306a54259cfe007db9e330e7ecf866 missing/invalid
$ hg tags
- abort: data/.hgtags.i@0c04f2a8af31: no match found!
- [255]
+ tip 5:8dbfe60eff30
+ bar 1:78391a272241
$ hg debugtagscache | tail -2
4 0c192d7d5e6b78a714de54a2e9627952a877e25a 0c04f2a8af31de17fab7422878ee5a2dadbc943d
- 5 8dbfe60eff306a54259cfe007db9e330e7ecf866 0c04f2a8af31de17fab7ffffffffffffffffffff
-# fix up the cache
- $ rm .hg/cache/hgtagsfnodes1
- $ hg tags -q
- tip
- bar
+ 5 8dbfe60eff306a54259cfe007db9e330e7ecf866 0c04f2a8af31de17fab7422878ee5a2dadbc943d
#if unix-permissions no-root
Errors writing to .hgtags fnodes cache are silently ignored