shared repository extension
Brendan Cully
brendan at kublai.com
Fri Nov 14 00:28:15 CST 2008
I've whipped up a little sugar for the symlink-.hg trick here:
http://hg.kublai.com/mercurial/extensions/sharedrepo/
It adds a --shared flag to the clone command. If you use it, the
working directory will share the repository of the source instead of
copying it. It's a lot like symlinking source/.hg/store to
dest/.hg/store, but should work in environments without symlinks.
This is only a proof of concept. I am thinking about extending it to
hide non-local revisions so that shared repositories appear more like
normal ones (until you delete the master repository!), but that'll
take a bit more effort.
For reference, the code looks like this:
-------------- next part --------------
# Shared repository extension
#
# Copyright 2008 Brendan Cully <brendan at kublai.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
'''shared repository support
This extension adds the --shared option to the clone command. When this
option is used, the destination uses the location passed as the argument
to --shared as its data store.
'''
from mercurial.i18n import _
from mercurial import commands, extensions, hg, localrepo, util
def sharedclone(orig, ui, source, dest=None, rev=None, noupdate=False, **kwargs):
"""
With --shared, clone will set up the destination to use the existing
source repository instead of creating a new one. The source repository
must be local.
"""
if kwargs.get('shared'):
if not hg.islocal(source):
raise util.Abort(_('source repository must be local'))
if dest is None:
dest = hg.defaultdest(source)
ui.status(_("destination directory: %s\n") % dest)
dest = hg.localpath(dest)
if not hg.islocal(dest):
raise util.Abort(_('destination repository must be local'))
s, d = hg.clone(ui, source, dest=dest, rev=['null'], update=False)
hgrc = d.opener('hgrc', 'a', text=True)
hgrc.write('\n[shared]\nrepository = %s\n' % s.root)
hgrc.close()
reqs = d.opener('requires', 'a', text=True)
reqs.write('shared\n')
reqs.close()
if not noupdate:
d = hg.repository(ui, dest)
d.ui.status(_("updating working directory\n"))
for test in (rev and rev[-1] or None, 'default', 'tip'):
try:
uprev = d.lookup(test)
break
except:
continue
hg.update(d, uprev)
return
return orig(ui, source, dest=dest, rev=rev, noupdate=noupdate, **kwargs)
def uisetup(ui):
desc = extensions.wrapcommand(commands.table, 'clone', sharedclone)
desc[0].__doc__ += sharedclone.__doc__
opts = desc[1]
opts.append(('', 'shared', None, _('reuse source repository')))
lr = localrepo.localrepository
lr.supported = tuple(list(lr.supported) + ['shared'])
def reposetup(ui, repo):
if repo.local():
spath = repo.ui.config('shared', 'repository')
if spath:
sr = hg.repository(ui, spath)
repo.store = sr.store
repo.sopener = sr.sopener
repo.spath = sr.spath
repo.sjoin = sr.sjoin
More information about the Mercurial
mailing list