sapling/sqldirstate/__init__.py
Mateusz Kwapich 6bc664f630 sqldirstate: change the migration message to be less ugly
Summary: .

Test Plan: works on my sandbox

Reviewers: ttung

Differential Revision: https://phabricator.intern.facebook.com/D3632494
2016-07-28 14:44:56 -07:00

138 lines
4.2 KiB
Python

# __init__.py - sqldirstate extension
#
# Copyright 2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
testedwith = 'internal'
from sqldirstate import makedirstate, DBFILE, toflat, tosql, writefakedirstate
from mercurial import commands, error, extensions, cmdutil, localrepo, util
from mercurial.i18n import _
from mercurial.extensions import wrapfunction
def issqldirstate(repo):
return util.safehasattr(repo, 'requirements') and \
'sqldirstate' in repo.requirements
def wrapjournalfiles(orig, self):
if issqldirstate(self):
files = ()
for vfs, filename in orig(self):
if filename != 'journal.dirstate':
files += ((vfs, filename),)
if not self.ui.configbool('sqldirstate', 'skipbackups', True):
files += ((self.vfs, 'journal.dirstate.sqlite3'),)
else:
files = orig(self)
return files
def wrapdirstate(orig, self):
ds = orig(self)
if issqldirstate(self):
ds.__class__ = makedirstate(ds.__class__)
ds._sqlinit()
# this is ugly hack turning off the dirstate invalidation
# on dirstate file change while working with sqldirstate repo
for currcls in localrepo.localrepository.__mro__:
if 'dirstate' in currcls.__dict__:
currcls.__dict__['dirstate'].paths = []
return ds
def wrapnewreporequirements(orig, repo):
reqs = orig(repo)
if repo.ui.configbool('format', 'sqldirstate', False):
reqs.add('sqldirstate')
return reqs
def wrapshelveaborttransaction(orig, repo):
if issqldirstate(repo):
tr = repo.currenttransaction()
repo.dirstate._writesqldirstate()
tr.abort()
else:
return orig(repo)
def upgrade(ui, repo):
if issqldirstate(repo):
raise error.Abort('repo already has sqldirstate')
wlock = repo.wlock()
try:
repo.dirstate._read()
tosql(repo.dirstate)
repo.requirements.add('sqldirstate')
repo._writerequirements()
if ui.configbool('sqldirstate', 'fakedirstate', True):
writefakedirstate(repo.dirstate)
else:
repo.dirstate._opener.unlink('dirstate')
del repo.dirstate
finally:
wlock.release()
def downgrade(ui, repo):
if not issqldirstate(repo):
raise error.Abort('repo doesn\'t have sqldirstate')
wlock = repo.lock()
try:
toflat(repo.dirstate)
repo.requirements.remove('sqldirstate')
repo._writerequirements()
repo.dirstate._opener.unlink('dirstate.sqlite3')
del repo.dirstate
finally:
wlock.release()
def wrappull(orig, ui, repo, *args, **kwargs):
if ui.configbool('sqldirstate', 'upgrade', False) and \
not issqldirstate(repo):
ui.status(_('migrating your repo to sqldirstate which will make your '
'hg commands faster...\n'))
upgrade(ui, repo)
return orig(ui, repo, *args, **kwargs)
def featuresetup(ui, supported):
# don't die on seeing a repo with the sqldirstate requirement
supported |= set(['sqldirstate'])
def extsetup(ui):
localrepo.localrepository.featuresetupfuncs.add(featuresetup)
wrapfunction(localrepo, 'newreporequirements',
wrapnewreporequirements)
wrapfunction(localrepo.localrepository, '_journalfiles',
wrapjournalfiles)
fcdescr = localrepo.localrepository.dirstate
wrapfunction(fcdescr, 'func', wrapdirstate)
fcdescr.paths = ()
try:
shelve = extensions.find('shelve')
wrapfunction(shelve, '_aborttransaction', wrapshelveaborttransaction)
except KeyError:
pass
extensions.wrapcommand(commands.table, 'pull', wrappull)
def reposetup(ui, repo):
ui.setconfig('sqldirstate', 'enabled', issqldirstate(repo))
# debug commands
cmdtable = {}
command = cmdutil.command(cmdtable)
@command('debugsqldirstate', [], 'hg debugsqldirstate [on|off]')
def debugsqldirstate(ui, repo, cmd, **opts):
""" migrate to sqldirstate """
if cmd == "on":
upgrade(ui, repo)
elif cmd == "off":
downgrade(ui, repo)
else:
raise error.Abort("bad command")