Mercurial > hg-stable
changeset 23063:cd86a6707159 stable
transactions: fix hg recover with fncache backups
The transaction backupfiles logic was broken for 'hg recover'. The file format
is XXX\0XXX\0YYY\0YYY\0 but the parser did a couple things wrong. 1) It went one
step beyond the final \0 and tried to read past the end of the array. 2)
array[i:i+1] returns a single item, instead of two items as intended.
Added a test to catch it, which turns out to be the first actual 'hg recover'
test.
author | Durham Goode <durham@fb.com> |
---|---|
date | Mon, 20 Oct 2014 16:53:56 -0700 |
parents | ba89f7b542c9 |
children | 5dc888b79e70 |
files | mercurial/transaction.py tests/test-fncache.t |
diffstat | 2 files changed, 46 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/transaction.py Sun Oct 19 16:48:33 2014 +0900 +++ b/mercurial/transaction.py Mon Oct 20 16:53:56 2014 -0700 @@ -349,8 +349,9 @@ data = fp.read() if len(data) > 0: parts = data.split('\0') - for i in xrange(0, len(parts), 2): - f, b = parts[i:i + 1] + # Skip the final part, since it's just a trailing empty space + for i in xrange(0, len(parts) - 1, 2): + f, b = parts[i:i + 2] backupentries.append((f, b, None)) _playback(file, report, opener, entries, backupentries)
--- a/tests/test-fncache.t Sun Oct 19 16:48:33 2014 +0900 +++ b/tests/test-fncache.t Mon Oct 20 16:53:56 2014 -0700 @@ -236,3 +236,46 @@ [255] $ cat .hg/store/fncache data/y.i + +Aborted transactions can be recovered later + + $ cat > ../exceptionext.py <<EOF + > import os + > from mercurial import commands, util, transaction + > from mercurial.extensions import wrapfunction + > + > def closewrapper(orig, self, *args, **kwargs): + > origonclose = self.onclose + > def onclose(): + > origonclose() + > raise util.Abort("forced transaction failure") + > self.onclose = onclose + > return orig(self, *args, **kwargs) + > + > def abortwrapper(orig, self, *args, **kwargs): + > raise util.Abort("forced transaction failure") + > + > def uisetup(ui): + > wrapfunction(transaction.transaction, 'close', closewrapper) + > wrapfunction(transaction.transaction, '_abort', abortwrapper) + > + > cmdtable = {} + > + > EOF + $ rm -f "${extpath}c" + $ hg up -q 1 + $ touch z + $ hg ci -qAm z 2>/dev/null + [255] + $ cat .hg/store/fncache | sort + data/y.i + data/z.i + $ hg recover + rolling back interrupted transaction + checking changesets + checking manifests + crosschecking files in changesets and manifests + checking files + 1 files, 1 changesets, 1 total revisions + $ cat .hg/store/fncache + data/y.i