D4536: hg: recognize include and exclude patterns when cloning
This revision was automatically updated to reflect the committed changes. Closed by commit rHG65b5900f30be: hg: recognize include and exclude patterns when cloning (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4536?vs=10913=10926 REVISION DETAIL https://phab.mercurial-scm.org/D4536 AFFECTED FILES mercurial/hg.py CHANGE DETAILS diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -35,6 +35,7 @@ logcmdutil, logexchange, merge as mergemod, +narrowspec, node, phases, scmutil, @@ -500,7 +501,8 @@ util.copyfile(srcbranchcache, dstbranchcache) def clone(ui, peeropts, source, dest=None, pull=False, revs=None, - update=True, stream=False, branch=None, shareopts=None): + update=True, stream=False, branch=None, shareopts=None, + storeincludepats=None, storeexcludepats=None): """Make a copy of an existing repository. Create a copy of an existing repository in a new directory. The @@ -542,6 +544,13 @@ repository. "identity" means the name is derived from the node of the first changeset in the repository. "remote" means the name is derived from the remote's path/URL. Defaults to "identity." + +storeincludepats and storeexcludepats: sets of file patterns to include and +exclude in the repository copy, respectively. If not defined, all files +will be included (a "full" clone). Otherwise a "narrow" clone containing +only the requested files will be performed. If ``storeincludepats`` is not +defined but ``storeexcludepats`` is, ``storeincludepats`` is assumed to be +``path:.``. If both are empty sets, no files will be cloned. """ if isinstance(source, bytes): @@ -574,6 +583,24 @@ elif destvfs.listdir(): raise error.Abort(_("destination '%s' is not empty") % dest) +createopts = {} +narrow = False + +if storeincludepats is not None: +narrowspec.validatepatterns(storeincludepats) +narrow = True + +if storeexcludepats is not None: +narrowspec.validatepatterns(storeexcludepats) +narrow = True + +if narrow: +# Include everything by default if only exclusion patterns defined. +if storeexcludepats and not storeincludepats: +storeincludepats = {'path:.'} + +createopts['narrowfiles'] = True + shareopts = shareopts or {} sharepool = shareopts.get('pool') sharenamemode = shareopts.get('mode') @@ -605,6 +632,11 @@ raise error.Abort(_('unknown share naming mode: %s') % sharenamemode) +# TODO this is a somewhat arbitrary restriction. +if narrow: +ui.status(_('(pooled storage not supported for narrow clones)\n')) +sharepath = None + if sharepath: return clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=pull, rev=revs, update=update, @@ -625,6 +657,10 @@ and not phases.hassecret(srcrepo)): copy = not pull and not revs +# TODO this is a somewhat arbitrary restriction. +if narrow: +copy = False + if copy: try: # we use a lock here because if we race with commit, we @@ -671,8 +707,9 @@ node=node.hex(node.nullid)) else: try: -destpeer = peer(srcrepo or ui, peeropts, dest, create=True) -# only pass ui when no srcrepo +# only pass ui when no srcrepo +destpeer = peer(srcrepo or ui, peeropts, dest, create=True, +createopts=createopts) except OSError as inst: if inst.errno == errno.EEXIST: cleandir = None @@ -714,6 +751,12 @@ exchange.pull(local, srcpeer, revs, streamclonerequested=stream) elif srcrepo: +# TODO lift restriction once exchange.push() accepts narrow +# push. +if narrow: +raise error.Abort(_('narrow clone not available for ' +'remote destinations')) + exchange.push(srcrepo, destpeer, revs=revs, bookmarks=srcrepo._bookmarks.keys()) else: To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4536: hg: recognize include and exclude patterns when cloning
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This commit teaches clone() to accept arguments defining file patterns to clone. This is the first step in teaching core code about the existence of a narrow clone. Right now, we only perform validation of the arguments and pass additional options into createopts to influence repository creation. Nothing of consequence happens with that creation option yet, however. For now, arbitrary restrictions exist, such as not allowing patterns for shared repos and disabling local copies when patterns are defined. We can potentially lift these restrictions in the future once partial clone/storage support is more flushed out. I figure it is best to reduce the surface area for bugs for the time being. It may seem weird to prefix these arguments with "store." However, clone is effectively pull + update and file patterns could apply to both the store and the working directory. The prefix is there to disambiguate in the future when this function may want to use different sets of patterns for the store and working directory. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4536 AFFECTED FILES mercurial/hg.py CHANGE DETAILS diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -35,6 +35,7 @@ logcmdutil, logexchange, merge as mergemod, +narrowspec, node, phases, scmutil, @@ -500,7 +501,8 @@ util.copyfile(srcbranchcache, dstbranchcache) def clone(ui, peeropts, source, dest=None, pull=False, revs=None, - update=True, stream=False, branch=None, shareopts=None): + update=True, stream=False, branch=None, shareopts=None, + storeincludepats=None, storeexcludepats=None): """Make a copy of an existing repository. Create a copy of an existing repository in a new directory. The @@ -542,6 +544,13 @@ repository. "identity" means the name is derived from the node of the first changeset in the repository. "remote" means the name is derived from the remote's path/URL. Defaults to "identity." + +storeincludepats and storeexcludepats: sets of file patterns to include and +exclude in the repository copy, respectively. If not defined, all files +will be included (a "full" clone). Otherwise a "narrow" clone containing +only the requested files will be performed. If ``storeincludepats`` is not +defined but ``storeexcludepats`` is, ``storeincludepats`` is assumed to be +``path:.``. If both are empty sets, no files will be cloned. """ if isinstance(source, bytes): @@ -574,6 +583,24 @@ elif destvfs.listdir(): raise error.Abort(_("destination '%s' is not empty") % dest) +createopts = {} +narrow = False + +if storeincludepats is not None: +narrowspec.validatepatterns(storeincludepats) +narrow = True + +if storeexcludepats is not None: +narrowspec.validatepatterns(storeexcludepats) +narrow = True + +if narrow: +# Include everything by default if only exclusion patterns defined. +if storeexcludepats and not storeincludepats: +storeincludepats = {'path:.'} + +createopts['narrowfiles'] = True + shareopts = shareopts or {} sharepool = shareopts.get('pool') sharenamemode = shareopts.get('mode') @@ -605,6 +632,11 @@ raise error.Abort(_('unknown share naming mode: %s') % sharenamemode) +# TODO this is a somewhat arbitrary restriction. +if narrow: +ui.status(_('(pooled storage not supported for narrow clones)\n')) +sharepath = None + if sharepath: return clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=pull, rev=revs, update=update, @@ -625,6 +657,10 @@ and not phases.hassecret(srcrepo)): copy = not pull and not revs +# TODO this is a somewhat arbitrary restriction. +if narrow: +copy = False + if copy: try: # we use a lock here because if we race with commit, we @@ -671,8 +707,9 @@ node=node.hex(node.nullid)) else: try: -destpeer = peer(srcrepo or ui, peeropts, dest, create=True) -# only pass ui when no srcrepo +# only pass ui when no srcrepo +destpeer = peer(srcrepo or ui, peeropts, dest, create=True, +createopts=createopts) except OSError as inst: if inst.errno == errno.EEXIST: cleandir = None @@ -714,6 +751,12 @@ exchange.pull(local, srcpeer, revs,