##// END OF EJS Templates
py3: replace os.sep with pycompat.ossep (part 3 of 4)
py3: replace os.sep with pycompat.ossep (part 3 of 4)

File last commit:

r29841:d5883fd0 default
r30615:bb77654d default
Show More
share.py
194 lines | 6.4 KiB | text/x-python | PythonLexer
Matt Mackall
share: add experimental share extension
r8801 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
share: add experimental share extension
r8801
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 '''share a common history between several working directories
Automatic Pooled Storage for Clones
-----------------------------------
When this extension is active, :hg:`clone` can be configured to
automatically share/pool storage across multiple clones. This
mode effectively converts :hg:`clone` to :hg:`clone` + :hg:`share`.
The benefit of using this mode is the automatic management of
store paths and intelligent pooling of related repositories.
The following ``share.`` config options influence this feature:
Matt Mackall
share: make option docs more check-config friendly
r25851 ``share.pool``
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 Filesystem path where shared repository data will be stored. When
defined, :hg:`clone` will automatically use shared repository
storage instead of creating a store inside each clone.
Matt Mackall
share: make option docs more check-config friendly
r25851 ``share.poolnaming``
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 How directory names in ``share.pool`` are constructed.
"identity" means the name is derived from the first changeset in the
repository. In this mode, different remotes share storage if their
root/initial changeset is identical. In this mode, the local shared
repository is an aggregate of all encountered remote repositories.
"remote" means the name is derived from the source repository's
path or URL. In this mode, storage is only shared if the path or URL
requested in the :hg:`clone` command matches exactly to a repository
that was cloned before.
The default naming mode is "identity."
'''
Dirkjan Ochtman
help: add/fix docstrings for a bunch of extensions
r8873
Pulkit Goyal
py3: make files use absolute_import and print_function...
r29485 from __future__ import absolute_import
import errno
Matt Mackall
share: add experimental share extension
r8801 from mercurial.i18n import _
Pulkit Goyal
py3: make files use absolute_import and print_function...
r29485 from mercurial import (
bookmarks,
cmdutil,
commands,
error,
extensions,
hg,
util,
)
repository = hg.repository
parseurl = hg.parseurl
Simon Heimberg
hgext: introduce unshare command
r15079
Gregory Szorc
share: declare commands using decorator
r21253 cmdtable = {}
command = cmdutil.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 testedwith = 'ships-with-hg-core'
Augie Fackler
hgext: mark all first-party extensions as such
r16743
Gregory Szorc
share: declare commands using decorator
r21253 @command('share',
Yuya Nishihara
commands: replace "working copy" with "working directory" in help/messages...
r24364 [('U', 'noupdate', None, _('do not create a working directory')),
Ryan McElroy
share: add option to share bookmarks...
r23614 ('B', 'bookmarks', None, _('also share bookmarks'))],
_('[-U] [-B] SOURCE [DEST]'),
Gregory Szorc
share: define norepo in command decorator
r21772 norepo=True)
Ryan McElroy
share: add option to share bookmarks...
r23614 def share(ui, source, dest=None, noupdate=False, bookmarks=False):
Martin Geisler
share: drop experimental label...
r10798 """create a new shared repository
Matt Mackall
share: add experimental share extension
r8801
Martin Geisler
share: wrap docstrings at 70 characters
r9273 Initialize a new repository and working directory that shares its
Ryan McElroy
share: add option to share bookmarks...
r23614 history (and optionally bookmarks) with another repository.
Matt Mackall
share: add experimental share extension
r8801
Erik Zielke
Use note admonition
r12389 .. note::
Simon Heimberg
documentation: add an extra newline after note directive...
r19997
Erik Zielke
Use note admonition
r12389 using rollback or extensions that destroy/modify history (mq,
rebase, etc.) can cause considerable confusion with shared
clones. In particular, if two shared clones are both updated to
the same changeset, and one of them destroys that changeset
with rollback, the other clone will suddenly stop working: all
operations will fail with "abort: working directory has unknown
parent". The only known workaround is to use debugsetparents on
Matt Mackall
share: remove reference to tip
r19399 the broken clone to reset it to a changeset that still exists.
Matt Mackall
share: add experimental share extension
r8801 """
Gregory Szorc
share: pass named arguments...
r27353 return hg.share(ui, source, dest=dest, update=not noupdate,
bookmarks=bookmarks)
Matt Mackall
share: add experimental share extension
r8801
Gregory Szorc
share: declare commands using decorator
r21253 @command('unshare', [], '')
Simon Heimberg
hgext: introduce unshare command
r15079 def unshare(ui, repo):
"""convert a shared repository to a normal one
Copy the store data to the repo and remove the sharedpath data.
"""
Angel Ezquerra
localrepo: introduce shared method to check if a repository is shared...
r23666 if not repo.shared():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("this is not a shared repo"))
Simon Heimberg
hgext: introduce unshare command
r15079
destlock = lock = None
lock = repo.lock()
try:
# we use locks here because if we race with commit, we
# can end up with extra data in the cloned revlogs that's
# not pointed to by changesets, thus causing verify to
# fail
destlock = hg.copystore(ui, repo, repo.path)
sharefile = repo.join('sharedpath')
util.rename(sharefile, sharefile + '.old')
repo.requirements.discard('sharedpath')
repo._writerequirements()
finally:
destlock and destlock.release()
lock and lock.release()
Siddharth Agarwal
share: replace reference to 'sopener' with 'svfs'...
r25666 # update store, spath, svfs and sjoin of repo
Brodie Rao
share: fix unshare calling wrong repo.__init__() method...
r20056 repo.unfiltered().__init__(repo.baseui, repo.root)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 # Wrap clone command to pass auto share options.
def clone(orig, ui, source, *args, **opts):
pool = ui.config('share', 'pool', None)
if pool:
pool = util.expandpath(pool)
opts['shareopts'] = dict(
pool=pool,
mode=ui.config('share', 'poolnaming', 'identity'),
)
return orig(ui, source, *args, **opts)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 def extsetup(ui):
Augie Fackler
bookmarks: hoist getbkfile out of bmstore class...
r27186 extensions.wrapfunction(bookmarks, '_getbkfile', getbkfile)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 extensions.wrapfunction(bookmarks.bmstore, 'recordchange', recordchange)
FUJIWARA Katsunori
share: wrap bmstore._writerepo for transaction sensitivity (issue4940)...
r26933 extensions.wrapfunction(bookmarks.bmstore, '_writerepo', writerepo)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 extensions.wrapcommand(commands.table, 'clone', clone)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
def _hassharedbookmarks(repo):
"""Returns whether this repo has shared bookmarks"""
try:
Angel Ezquerra
share: replace the bookmarks.shared file with an entry on a new "shared" file...
r23883 shared = repo.vfs.read('shared').splitlines()
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as inst:
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if inst.errno != errno.ENOENT:
raise
return False
Martijn Pieters
share: move magic string to a constant
r29424 return hg.sharedbookmarks in shared
Ryan McElroy
share: implement shared bookmark functionality...
r23548
def _getsrcrepo(repo):
"""
Returns the source repository object for a given shared repository.
If repo is not a shared repository, return None.
"""
Matt Harbison
share: use the 'sharedpath' attr on repo instead of reloading from the file...
r23626 if repo.sharedpath == repo.path:
return None
Durham Goode
share: don't recreate the source repo each time...
r29506 if util.safehasattr(repo, 'srcrepo') and repo.srcrepo:
return repo.srcrepo
Matt Harbison
share: use the 'sharedpath' attr on repo instead of reloading from the file...
r23626 # the sharedpath always ends in the .hg; we want the path to the repo
source = repo.vfs.split(repo.sharedpath)[0]
srcurl, branches = parseurl(source)
Durham Goode
share: don't recreate the source repo each time...
r29506 srcrepo = repository(repo.ui, srcurl)
repo.srcrepo = srcrepo
return srcrepo
Ryan McElroy
share: implement shared bookmark functionality...
r23548
Augie Fackler
bookmarks: hoist getbkfile out of bmstore class...
r27186 def getbkfile(orig, repo):
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if _hassharedbookmarks(repo):
srcrepo = _getsrcrepo(repo)
if srcrepo is not None:
repo = srcrepo
Augie Fackler
bookmarks: hoist getbkfile out of bmstore class...
r27186 return orig(repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
def recordchange(orig, self, tr):
# Continue with write to local bookmarks file as usual
orig(self, tr)
if _hassharedbookmarks(self._repo):
srcrepo = _getsrcrepo(self._repo)
if srcrepo is not None:
category = 'share-bookmarks'
tr.addpostclose(category, lambda tr: self._writerepo(srcrepo))
FUJIWARA Katsunori
share: wrap bmstore._writerepo for transaction sensitivity (issue4940)...
r26933 def writerepo(orig, self, repo):
Ryan McElroy
share: implement shared bookmark functionality...
r23548 # First write local bookmarks file in case we ever unshare
FUJIWARA Katsunori
share: wrap bmstore._writerepo for transaction sensitivity (issue4940)...
r26933 orig(self, repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if _hassharedbookmarks(self._repo):
srcrepo = _getsrcrepo(self._repo)
if srcrepo is not None:
FUJIWARA Katsunori
share: wrap bmstore._writerepo for transaction sensitivity (issue4940)...
r26933 orig(self, srcrepo)