subrepo: use per-type config options to enable subrepos
We change subrepos.allowed from a list of allowed subrepo types to
a combination of a master switch and per-type boolean flag.
If the master switch is set, subrepos can be disabled wholesale.
If subrepos are globally enabled, then per-type options are
consulted. Mercurial repos are enabled by default. Everything else
is disabled by default.
--- a/mercurial/configitems.py Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/configitems.py Mon Nov 06 22:32:41 2017 -0800
@@ -814,6 +814,15 @@
coreconfigitem('subrepos', 'allowed',
default=dynamicdefault, # to make backporting simpler
)
+coreconfigitem('subrepos', 'hg:allowed',
+ default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'git:allowed',
+ default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'svn:allowed',
+ default=dynamicdefault,
+)
coreconfigitem('templates', '.*',
default=None,
generic=True,
--- a/mercurial/help/config.txt Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/help/config.txt Mon Nov 06 22:32:41 2017 -0800
@@ -1899,20 +1899,40 @@
This section contains options that control the behavior of the
subrepositories feature. See also :hg:`help subrepos`.
+Security note: auditing in Mercurial is known to be insufficient to
+prevent clone-time code execution with carefully constructed Git
+subrepos. It is unknown if a similar detect is present in Subversion
+subrepos. Both Git and Subversion subrepos are disabled by default
+out of security concerns. These subrepo types can be enabled using
+the respective options below.
+
``allowed``
- List of subrepository types (hg, git, svn) allowed in the working
- directory.
-
- When disallowed, any commands including :hg:`update` will fail if
- subrepositories are involved.
-
- Security note: auditing in Mercurial is known to be insufficient
- to prevent clone-time code execution with carefully constructed
- Git subrepos. It is unknown if a similar defect is present in
- Subversion subrepos, so both are disabled by default out of an
- abundance of caution. Re-enable such subrepos via this setting
- with caution.
- (default: `hg`)
+ Whether subrepositories are allowed in the working directory.
+
+ When false, commands involving subrepositories (like :hg:`update`)
+ will fail for all subrepository types.
+ (default: true)
+
+``hg:allowed``
+ Whether Mercurial subrepositories are allowed in the working
+ directory. This option only has an effect if ``subrepos.allowed``
+ is true.
+ (default: true)
+
+``git:allowed``
+ Whether Git subrepositories are allowed in the working directory.
+ This option only has an effect if ``subrepos.allowed`` is true.
+
+ See the security note above before enabling Git subrepos.
+ (default: false)
+
+``svn:allowed``
+ Whether Subversion subrepositories are allowed in the working
+ directory. This option only has an effect if ``subrepos.allowed``
+ is true.
+
+ See the security note above before enabling Subversion subrepos.
+ (default: false)
``templatealias``
-----------------
--- a/mercurial/subrepo.py Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/subrepo.py Mon Nov 06 22:32:41 2017 -0800
@@ -365,10 +365,24 @@
if repo.wvfs.islink(path):
raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
+SUBREPO_ALLOWED_DEFAULTS = {
+ 'hg': True,
+ 'git': False,
+ 'svn': False,
+}
+
def _checktype(ui, kind):
- if kind not in ui.configlist('subrepos', 'allowed', ['hg']):
- raise error.Abort(_("subrepo type %s not allowed") % kind,
+ # subrepos.allowed is a master kill switch. If disabled, subrepos are
+ # disabled period.
+ if not ui.configbool('subrepos', 'allowed', True):
+ raise error.Abort(_('subrepos not enabled'),
hint=_("see 'hg help config.subrepos' for details"))
+
+ default = SUBREPO_ALLOWED_DEFAULTS.get(kind, False)
+ if not ui.configbool('subrepos', '%s:allowed' % kind, default):
+ raise error.Abort(_('%s subrepos not allowed') % kind,
+ hint=_("see 'hg help config.subrepos' for details"))
+
if kind not in types:
raise error.Abort(_('unknown subrepo type %s') % kind)
--- a/tests/test-convert-git.t Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-convert-git.t Mon Nov 06 22:32:41 2017 -0800
@@ -8,7 +8,7 @@
$ echo "convert=" >> $HGRCPATH
$ cat >> $HGRCPATH <<EOF
> [subrepos]
- > allowed = hg, git
+ > git:allowed = true
> EOF
$ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
$ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
--- a/tests/test-mq-subrepo-svn.t Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-mq-subrepo-svn.t Mon Nov 06 22:32:41 2017 -0800
@@ -6,7 +6,8 @@
> [diff]
> nodates = 1
> [subrepos]
- > allowed = hg, svn
+ > allowed = true
+ > svn:allowed = true
> EOF
fn to create new repository, and cd into it
--- a/tests/test-subrepo-git.t Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo-git.t Mon Nov 06 22:32:41 2017 -0800
@@ -45,7 +45,7 @@
git subrepo is disabled by default
$ hg commit -m 'new git subrepo'
- abort: subrepo type git not allowed
+ abort: git subrepos not allowed
(see 'hg help config.subrepos' for details)
[255]
@@ -53,7 +53,7 @@
$ cat >> $HGRCPATH <<EOF
> [subrepos]
- > allowed = hg, git
+ > git:allowed = true
> EOF
$ hg commit -m 'new git subrepo'
@@ -106,30 +106,22 @@
clone with subrepo disabled (update should fail)
- $ hg clone t -U tc2 --config subrepos.allowed=
- $ hg update -R tc2 --config subrepos.allowed=
- abort: subrepo type git not allowed
+ $ hg clone t -U tc2 --config subrepos.allowed=false
+ $ hg update -R tc2 --config subrepos.allowed=false
+ abort: subrepos not enabled
(see 'hg help config.subrepos' for details)
[255]
$ ls tc2
a
- $ hg clone t tc3 --config subrepos.allowed=
+ $ hg clone t tc3 --config subrepos.allowed=false
updating to branch default
- abort: subrepo type git not allowed
+ abort: subrepos not enabled
(see 'hg help config.subrepos' for details)
[255]
$ ls tc3
a
- $ hg clone t tc4 --config subrepos.allowed=hg
- updating to branch default
- abort: subrepo type git not allowed
- (see 'hg help config.subrepos' for details)
- [255]
- $ ls tc4
- a
-
update to previous substate
$ cd tc
--- a/tests/test-subrepo-svn.t Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo-svn.t Mon Nov 06 22:32:41 2017 -0800
@@ -61,7 +61,7 @@
svn subrepo is disabled by default
$ hg ci -m1
- abort: subrepo type svn not allowed
+ abort: svn subrepos not allowed
(see 'hg help config.subrepos' for details)
[255]
@@ -69,7 +69,7 @@
$ cat >> $HGRCPATH <<EOF
> [subrepos]
- > allowed = hg, svn
+ > svn:allowed = true
> EOF
$ hg ci -m1
--- a/tests/test-subrepo.t Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo.t Mon Nov 06 22:32:41 2017 -0800
@@ -488,30 +488,40 @@
clone with subrepo disabled (update should fail)
- $ hg clone t -U tc2 --config subrepos.allowed=
- $ hg update -R tc2 --config subrepos.allowed=
- abort: subrepo type hg not allowed
+ $ hg clone t -U tc2 --config subrepos.allowed=false
+ $ hg update -R tc2 --config subrepos.allowed=false
+ abort: subrepos not enabled
(see 'hg help config.subrepos' for details)
[255]
$ ls tc2
a
- $ hg clone t tc3 --config subrepos.allowed=
+ $ hg clone t tc3 --config subrepos.allowed=false
updating to branch default
- abort: subrepo type hg not allowed
+ abort: subrepos not enabled
(see 'hg help config.subrepos' for details)
[255]
$ ls tc3
a
- $ hg clone t tc4 --config subrepos.allowed=git
- updating to branch default
- abort: subrepo type hg not allowed
+And again with just the hg type disabled
+
+ $ hg clone t -U tc4 --config subrepos.hg:allowed=false
+ $ hg update -R tc4 --config subrepos.hg:allowed=false
+ abort: hg subrepos not allowed
(see 'hg help config.subrepos' for details)
[255]
$ ls tc4
a
+ $ hg clone t tc5 --config subrepos.hg:allowed=false
+ updating to branch default
+ abort: hg subrepos not allowed
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc5
+ a
+
push
$ cd tc