transaction: automatically clean up empty abandoned txs

Summary:
When creating a transaction we now automatically clean up an existing (abandoned) transaction if it is empty. This seems safe since recover() should be a no-op (other than cleaning up the tx files).

I've seen multiple cases of empty transaction files due to commands crashing/being killed in a transaction (but before anything has been written).

Reviewed By: quark-zju

Differential Revision: D33482320

fbshipit-source-id: a6ef74a30de96c600385a701ab2ab61bb149afb9
This commit is contained in:
Muir Manders 2022-01-10 18:35:03 -08:00 committed by Facebook GitHub Bot
parent bc69c27d3b
commit e75c4ca2d8
3 changed files with 24 additions and 8 deletions

View File

@ -1665,12 +1665,21 @@ class localrepository(object):
if tr is not None:
return tr.nest()
# abort here if the journal already exists
if self.svfs.exists("journal"):
raise errormod.AbandonedTransactionFoundError(
_("abandoned transaction found"),
hint=_("run 'hg recover' to clean up transaction"),
)
try:
stat = self.svfs.stat("journal")
except FileNotFoundError:
# No existing transaction - this is the normal case.
pass
else:
if stat.st_size > 0:
# Non-empty transaction already exists - bail.
raise errormod.AbandonedTransactionFoundError(
_("abandoned transaction found"),
hint=_("run 'hg recover' to clean up transaction"),
)
else:
self.ui.status(_("cleaning up empty abandoned transaction\n"))
self.recover()
idbase = b"%.40f#%f" % (random.random(), time.time())
ha = hex(hashlib.sha1(idbase).digest())

View File

@ -9,7 +9,7 @@
$ newclientrepo foo test:repo_server book
$ cd ../repo
$ touch .hg/store/journal
$ echo something > .hg/store/journal
$ echo foo > a
$ hg ci -Am0
@ -19,3 +19,10 @@
$ hg recover
rolling back interrupted transaction
couldn't read journal entry 'something\n'!
Empty journal is cleaned up automatically.
$ touch .hg/store/journal
$ hg ci -Am0
cleaning up empty abandoned transaction
rolling back interrupted transaction

View File

@ -567,7 +567,7 @@ Migration up
$ setconfig visibility.enabled=true
(Test if the repo contains an abandoned transaction, the auto migration does not crash)
$ touch .hg/store/journal
$ echo something > .hg/store/journal
$ hg debugedenimporthelper --get-manifest-node df4f53cec30af1e4f669102135076fd4f9673fcc
switching to explicit tracking of visible commits
4e7eb8574ed56675aa89d2b5abbced12d5688cef