##// END OF EJS Templates
py3: replace `pycompat.xrange` by `range`
py3: replace `pycompat.xrange` by `range`

File last commit:

r49730:6000f5b2 default
r50179:d44e3c45 default
Show More
share.py
235 lines | 7.8 KiB | text/x-python | PythonLexer
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2006, 2007 Olivia Mackall <olivia@selenic.com>
Matt Mackall
share: add experimental share extension
r8801 #
# 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
Joerg Sonnenberger
share: provide a more useful text for hg help...
r45535 The share extension introduces a new command :hg:`share` to create a new
working directory. This is similar to :hg:`clone`, but doesn't involve
copying or linking the storage of the repository. This allows working on
different branches or changes in parallel without the associated cost in
terms of disk space.
Note: destructive operations or extensions like :hg:`rollback` should be
used with care as they can result in confusing problems.
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 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.
Matt Harbison
help: minor copy editing for grammar
r34950 The default naming mode is "identity".
Pulkit Goyal
share: add documentation about share-safe mode in `hg help -e share`...
r46621
.. container:: verbose
Martin von Zweigbergk
share: remove unexpected heading from "verbose" container in help test...
r46698 Sharing requirements and configs of source repository with shares:
Pulkit Goyal
share: add documentation about share-safe mode in `hg help -e share`...
r46621
By default creating a shared repository only enables sharing a common
history and does not share requirements and configs between them. This
may lead to problems in some cases, for example when you upgrade the
storage format from one repository but does not set related configs
in the shares.
Setting `format.exp-share-safe = True` enables sharing configs and
requirements. This only applies to shares which are done after enabling
the config option.
For enabling this in existing shares, enable the config option and reshare.
For resharing existing shares, make sure your working directory is clean
and there are no untracked files, delete that share and create a new share.
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 '''
Dirkjan Ochtman
help: add/fix docstrings for a bunch of extensions
r8873
Pulkit Goyal
py3: make files use absolute_import and print_function...
r29485
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,
commands,
error,
extensions,
hg,
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 registrar,
FUJIWARA Katsunori
bookmarks: check HG_PENDING strictly...
r31052 txnutil,
Pulkit Goyal
py3: make files use absolute_import and print_function...
r29485 util,
)
Gregory Szorc
share: declare commands using decorator
r21253 cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 command = registrar.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
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testedwith = b'ships-with-hg-core'
Augie Fackler
hgext: mark all first-party extensions as such
r16743
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'share',
Augie Fackler
formatting: blacken the codebase...
r43346 [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'U', b'noupdate', None, _(b'do not create a working directory')),
(b'B', b'bookmarks', None, _(b'also share bookmarks')),
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 (
b'',
b'relative',
None,
_(b'point to source using a relative path'),
),
Dan Villiom Podlaski Christiansen
share: add --relative flag to store a relative path to the source...
r31133 ],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'[-U] [-B] SOURCE [DEST]'),
rdamazio@google.com
help: assigning categories to existing commands...
r40329 helpcategory=command.CATEGORY_REPO_CREATION,
Augie Fackler
formatting: blacken the codebase...
r43346 norepo=True,
)
def share(
ui, source, dest=None, noupdate=False, bookmarks=False, relative=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 """
Augie Fackler
formatting: blacken the codebase...
r43346 hg.share(
ui,
source,
dest=dest,
update=not noupdate,
bookmarks=bookmarks,
relative=relative,
)
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 return 0
Matt Mackall
share: add experimental share extension
r8801
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @command(b'unshare', [], b'', helpcategory=command.CATEGORY_MAINTENANCE)
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():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"this is not a shared repo"))
Simon Heimberg
hgext: introduce unshare command
r15079
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879 hg.unshare(ui, repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pool = ui.config(b'share', b'pool')
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 if pool:
pool = util.expandpath(pool)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 opts['shareopts'] = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'pool': pool,
b'mode': ui.config(b'share', b'poolnaming'),
Yuya Nishihara
share: use dict literal instead of dict(key=value)...
r33021 }
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
return orig(ui, source, *args, **opts)
Augie Fackler
formatting: blacken the codebase...
r43346
Ryan McElroy
share: implement shared bookmark functionality...
r23548 def extsetup(ui):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extensions.wrapfunction(bookmarks, b'_getbkfile', getbkfile)
extensions.wrapfunction(bookmarks.bmstore, b'_recordchange', recordchange)
extensions.wrapfunction(bookmarks.bmstore, b'_writerepo', writerepo)
extensions.wrapcommand(commands.table, b'clone', clone)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
Augie Fackler
formatting: blacken the codebase...
r43346
Ryan McElroy
share: implement shared bookmark functionality...
r23548 def _hassharedbookmarks(repo):
"""Returns whether this repo has shared bookmarks"""
Martin von Zweigbergk
bookmarks: keep bookmarks in .hg/store if new config set...
r42512 if bookmarks.bookmarksinstore(repo):
# Kind of a lie, but it means that we skip our custom reads and writes
# from/to the source repo.
return False
Ryan McElroy
share: implement shared bookmark functionality...
r23548 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shared = repo.vfs.read(b'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
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Gregory Szorc
hg: move share._getsrcrepo into core...
r36177 srcrepo = hg.sharedreposource(repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if srcrepo is not None:
FUJIWARA Katsunori
bookmarks: check HG_PENDING strictly...
r31052 # just orig(srcrepo) doesn't work as expected, because
# HG_PENDING refers repo.root.
try:
Augie Fackler
formatting: blacken the codebase...
r43346 fp, pending = txnutil.trypending(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.root, repo.vfs, b'bookmarks'
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
bookmarks: check HG_PENDING strictly...
r31052 if pending:
# only in this case, bookmark information in repo
# is up-to-date.
return fp
fp.close()
except IOError as inst:
if inst.errno != errno.ENOENT:
raise
# otherwise, we should read bookmarks from srcrepo,
# because .hg/bookmarks in srcrepo might be already
# changed via another sharing repo
Ryan McElroy
share: implement shared bookmark functionality...
r23548 repo = srcrepo
FUJIWARA Katsunori
bookmarks: check HG_PENDING strictly...
r31052
# TODO: Pending changes in repo are still invisible in
# srcrepo, because bookmarks.pending is written only into repo.
# See also https://www.mercurial-scm.org/wiki/SharedRepository
Augie Fackler
bookmarks: hoist getbkfile out of bmstore class...
r27186 return orig(repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Gregory Szorc
hg: move share._getsrcrepo into core...
r36177 srcrepo = hg.sharedreposource(self._repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if srcrepo is not None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 category = b'share-bookmarks'
Ryan McElroy
share: implement shared bookmark functionality...
r23548 tr.addpostclose(category, lambda tr: self._writerepo(srcrepo))
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Gregory Szorc
hg: move share._getsrcrepo into core...
r36177 srcrepo = hg.sharedreposource(self._repo)
Ryan McElroy
share: implement shared bookmark functionality...
r23548 if srcrepo is not None:
FUJIWARA Katsunori
share: wrap bmstore._writerepo for transaction sensitivity (issue4940)...
r26933 orig(self, srcrepo)