##// END OF EJS Templates
merge with stable
Augie Fackler -
r34997:602c168c merge default
parent child Browse files
Show More
@@ -0,0 +1,132 b''
1 Test illegal name
2 -----------------
3
4 on commit:
5
6 $ hg init hgname
7 $ cd hgname
8 $ mkdir sub
9 $ hg init sub/.hg
10 $ echo 'sub/.hg = sub/.hg' >> .hgsub
11 $ hg ci -qAm 'add subrepo "sub/.hg"'
12 abort: path 'sub/.hg' is inside nested repo 'sub'
13 [255]
14
15 prepare tampered repo (including the commit above):
16
17 $ hg import --bypass -qm 'add subrepo "sub/.hg"' - <<'EOF'
18 > diff --git a/.hgsub b/.hgsub
19 > new file mode 100644
20 > --- /dev/null
21 > +++ b/.hgsub
22 > @@ -0,0 +1,1 @@
23 > +sub/.hg = sub/.hg
24 > diff --git a/.hgsubstate b/.hgsubstate
25 > new file mode 100644
26 > --- /dev/null
27 > +++ b/.hgsubstate
28 > @@ -0,0 +1,1 @@
29 > +0000000000000000000000000000000000000000 sub/.hg
30 > EOF
31 $ cd ..
32
33 on clone (and update):
34
35 $ hg clone -q hgname hgname2
36 abort: path 'sub/.hg' is inside nested repo 'sub'
37 [255]
38
39 Test direct symlink traversal
40 -----------------------------
41
42 #if symlink
43
44 on commit:
45
46 $ mkdir hgsymdir
47 $ hg init hgsymdir/root
48 $ cd hgsymdir/root
49 $ ln -s ../out
50 $ hg ci -qAm 'add symlink "out"'
51 $ hg init ../out
52 $ echo 'out = out' >> .hgsub
53 $ hg ci -qAm 'add subrepo "out"'
54 abort: subrepo 'out' traverses symbolic link
55 [255]
56
57 prepare tampered repo (including the commit above):
58
59 $ hg import --bypass -qm 'add subrepo "out"' - <<'EOF'
60 > diff --git a/.hgsub b/.hgsub
61 > new file mode 100644
62 > --- /dev/null
63 > +++ b/.hgsub
64 > @@ -0,0 +1,1 @@
65 > +out = out
66 > diff --git a/.hgsubstate b/.hgsubstate
67 > new file mode 100644
68 > --- /dev/null
69 > +++ b/.hgsubstate
70 > @@ -0,0 +1,1 @@
71 > +0000000000000000000000000000000000000000 out
72 > EOF
73 $ cd ../..
74
75 on clone (and update):
76
77 $ mkdir hgsymdir2
78 $ hg clone -q hgsymdir/root hgsymdir2/root
79 abort: subrepo 'out' traverses symbolic link
80 [255]
81 $ ls hgsymdir2
82 root
83
84 #endif
85
86 Test indirect symlink traversal
87 -------------------------------
88
89 #if symlink
90
91 on commit:
92
93 $ mkdir hgsymin
94 $ hg init hgsymin/root
95 $ cd hgsymin/root
96 $ ln -s ../out
97 $ hg ci -qAm 'add symlink "out"'
98 $ mkdir ../out
99 $ hg init ../out/sub
100 $ echo 'out/sub = out/sub' >> .hgsub
101 $ hg ci -qAm 'add subrepo "out/sub"'
102 abort: path 'out/sub' traverses symbolic link 'out'
103 [255]
104
105 prepare tampered repo (including the commit above):
106
107 $ hg import --bypass -qm 'add subrepo "out/sub"' - <<'EOF'
108 > diff --git a/.hgsub b/.hgsub
109 > new file mode 100644
110 > --- /dev/null
111 > +++ b/.hgsub
112 > @@ -0,0 +1,1 @@
113 > +out/sub = out/sub
114 > diff --git a/.hgsubstate b/.hgsubstate
115 > new file mode 100644
116 > --- /dev/null
117 > +++ b/.hgsubstate
118 > @@ -0,0 +1,1 @@
119 > +0000000000000000000000000000000000000000 out/sub
120 > EOF
121 $ cd ../..
122
123 on clone (and update):
124
125 $ mkdir hgsymin2
126 $ hg clone -q hgsymin/root hgsymin2/root
127 abort: path 'out/sub' traverses symbolic link 'out'
128 [255]
129 $ ls hgsymin2
130 root
131
132 #endif
@@ -154,3 +154,4 b' 920977f72c7b70acfdaf56ab35360584d7845827'
154 2f427b57bf9019c6dc3750baa539dc22c1be50f6 0 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
@@ -167,3 +167,4 b' 920977f72c7b70acfdaf56ab35360584d7845827'
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
@@ -63,16 +63,6 b' command = registrar.command(cmdtable)'
63 # leave the attribute unspecified.
63 # leave the attribute unspecified.
64 testedwith = 'ships-with-hg-core'
64 testedwith = 'ships-with-hg-core'
65
65
66 configtable = {}
67 configitem = registrar.configitem(configtable)
68
69 configitem('share', 'pool',
70 default=None,
71 )
72 configitem('share', 'poolnaming',
73 default='identity',
74 )
75
76 @command('share',
66 @command('share',
77 [('U', 'noupdate', None, _('do not create a working directory')),
67 [('U', 'noupdate', None, _('do not create a working directory')),
78 ('B', 'bookmarks', None, _('also share bookmarks')),
68 ('B', 'bookmarks', None, _('also share bookmarks')),
@@ -570,9 +570,8 b' def _conflictsmsg(repo):'
570 unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
570 unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
571 if unresolvedlist:
571 if unresolvedlist:
572 mergeliststr = '\n'.join(
572 mergeliststr = '\n'.join(
573 [' %s' % os.path.relpath(
573 [' %s' % util.pathto(repo.root, pycompat.getcwd(), path)
574 os.path.join(repo.root, path),
574 for path in unresolvedlist])
575 pycompat.getcwd()) for path in unresolvedlist])
576 msg = _('''Unresolved merge conflicts:
575 msg = _('''Unresolved merge conflicts:
577
576
578 %s
577 %s
@@ -787,6 +787,12 b" coreconfigitem('server', 'validate',"
787 coreconfigitem('server', 'zliblevel',
787 coreconfigitem('server', 'zliblevel',
788 default=-1,
788 default=-1,
789 )
789 )
790 coreconfigitem('share', 'pool',
791 default=None,
792 )
793 coreconfigitem('share', 'poolnaming',
794 default='identity',
795 )
790 coreconfigitem('smtp', 'host',
796 coreconfigitem('smtp', 'host',
791 default=None,
797 default=None,
792 )
798 )
@@ -808,6 +814,18 b" coreconfigitem('smtp', 'username',"
808 coreconfigitem('sparse', 'missingwarning',
814 coreconfigitem('sparse', 'missingwarning',
809 default=True,
815 default=True,
810 )
816 )
817 coreconfigitem('subrepos', 'allowed',
818 default=dynamicdefault, # to make backporting simpler
819 )
820 coreconfigitem('subrepos', 'hg:allowed',
821 default=dynamicdefault,
822 )
823 coreconfigitem('subrepos', 'git:allowed',
824 default=dynamicdefault,
825 )
826 coreconfigitem('subrepos', 'svn:allowed',
827 default=dynamicdefault,
828 )
811 coreconfigitem('templates', '.*',
829 coreconfigitem('templates', '.*',
812 default=None,
830 default=None,
813 generic=True,
831 generic=True,
@@ -1893,6 +1893,47 b' rewrite rules are then applied on the fu'
1893 doesn't match the full path, an attempt is made to apply it on the
1893 doesn't match the full path, an attempt is made to apply it on the
1894 relative path alone. The rules are applied in definition order.
1894 relative path alone. The rules are applied in definition order.
1895
1895
1896 ``subrepos``
1897 ------------
1898
1899 This section contains options that control the behavior of the
1900 subrepositories feature. See also :hg:`help subrepos`.
1901
1902 Security note: auditing in Mercurial is known to be insufficient to
1903 prevent clone-time code execution with carefully constructed Git
1904 subrepos. It is unknown if a similar detect is present in Subversion
1905 subrepos. Both Git and Subversion subrepos are disabled by default
1906 out of security concerns. These subrepo types can be enabled using
1907 the respective options below.
1908
1909 ``allowed``
1910 Whether subrepositories are allowed in the working directory.
1911
1912 When false, commands involving subrepositories (like :hg:`update`)
1913 will fail for all subrepository types.
1914 (default: true)
1915
1916 ``hg:allowed``
1917 Whether Mercurial subrepositories are allowed in the working
1918 directory. This option only has an effect if ``subrepos.allowed``
1919 is true.
1920 (default: true)
1921
1922 ``git:allowed``
1923 Whether Git subrepositories are allowed in the working directory.
1924 This option only has an effect if ``subrepos.allowed`` is true.
1925
1926 See the security note above before enabling Git subrepos.
1927 (default: false)
1928
1929 ``svn:allowed``
1930 Whether Subversion subrepositories are allowed in the working
1931 directory. This option only has an effect if ``subrepos.allowed``
1932 is true.
1933
1934 See the security note above before enabling Subversion subrepos.
1935 (default: false)
1936
1896 ``templatealias``
1937 ``templatealias``
1897 -----------------
1938 -----------------
1898
1939
@@ -243,7 +243,9 b' def share(ui, source, dest=None, update='
243 try:
243 try:
244 sharedpath = os.path.relpath(sharedpath, destvfs.base)
244 sharedpath = os.path.relpath(sharedpath, destvfs.base)
245 requirements += 'relshared\n'
245 requirements += 'relshared\n'
246 except IOError as e:
246 except (IOError, ValueError) as e:
247 # ValueError is raised on Windows if the drive letters differ on
248 # each path
247 raise error.Abort(_('cannot calculate relative path'),
249 raise error.Abort(_('cannot calculate relative path'),
248 hint=str(e))
250 hint=str(e))
249 else:
251 else:
@@ -135,7 +135,47 b' class pathauditor(object):'
135 return False
135 return False
136
136
137 def canonpath(root, cwd, myname, auditor=None):
137 def canonpath(root, cwd, myname, auditor=None):
138 '''return the canonical path of myname, given cwd and root'''
138 '''return the canonical path of myname, given cwd and root
139
140 >>> def check(root, cwd, myname):
141 ... a = pathauditor(root, realfs=False)
142 ... try:
143 ... return canonpath(root, cwd, myname, a)
144 ... except error.Abort:
145 ... return 'aborted'
146 >>> def unixonly(root, cwd, myname, expected='aborted'):
147 ... if pycompat.iswindows:
148 ... return expected
149 ... return check(root, cwd, myname)
150 >>> def winonly(root, cwd, myname, expected='aborted'):
151 ... if not pycompat.iswindows:
152 ... return expected
153 ... return check(root, cwd, myname)
154 >>> winonly(b'd:\\\\repo', b'c:\\\\dir', b'filename')
155 'aborted'
156 >>> winonly(b'c:\\\\repo', b'c:\\\\dir', b'filename')
157 'aborted'
158 >>> winonly(b'c:\\\\repo', b'c:\\\\', b'filename')
159 'aborted'
160 >>> winonly(b'c:\\\\repo', b'c:\\\\', b'repo\\\\filename',
161 ... b'filename')
162 'filename'
163 >>> winonly(b'c:\\\\repo', b'c:\\\\repo', b'filename', b'filename')
164 'filename'
165 >>> winonly(b'c:\\\\repo', b'c:\\\\repo\\\\subdir', b'filename',
166 ... b'subdir/filename')
167 'subdir/filename'
168 >>> unixonly(b'/repo', b'/dir', b'filename')
169 'aborted'
170 >>> unixonly(b'/repo', b'/', b'filename')
171 'aborted'
172 >>> unixonly(b'/repo', b'/', b'repo/filename', b'filename')
173 'filename'
174 >>> unixonly(b'/repo', b'/repo', b'filename', b'filename')
175 'filename'
176 >>> unixonly(b'/repo', b'/repo/subdir', b'filename', b'subdir/filename')
177 'subdir/filename'
178 '''
139 if util.endswithsep(root):
179 if util.endswithsep(root):
140 rootsep = root
180 rootsep = root
141 else:
181 else:
@@ -359,6 +359,33 b' def _sanitize(ui, vfs, ignore):'
359 "in '%s'\n") % vfs.join(dirname))
359 "in '%s'\n") % vfs.join(dirname))
360 vfs.unlink(vfs.reljoin(dirname, f))
360 vfs.unlink(vfs.reljoin(dirname, f))
361
361
362 def _auditsubrepopath(repo, path):
363 # auditor doesn't check if the path itself is a symlink
364 pathutil.pathauditor(repo.root)(path)
365 if repo.wvfs.islink(path):
366 raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
367
368 SUBREPO_ALLOWED_DEFAULTS = {
369 'hg': True,
370 'git': False,
371 'svn': False,
372 }
373
374 def _checktype(ui, kind):
375 # subrepos.allowed is a master kill switch. If disabled, subrepos are
376 # disabled period.
377 if not ui.configbool('subrepos', 'allowed', True):
378 raise error.Abort(_('subrepos not enabled'),
379 hint=_("see 'hg help config.subrepos' for details"))
380
381 default = SUBREPO_ALLOWED_DEFAULTS.get(kind, False)
382 if not ui.configbool('subrepos', '%s:allowed' % kind, default):
383 raise error.Abort(_('%s subrepos not allowed') % kind,
384 hint=_("see 'hg help config.subrepos' for details"))
385
386 if kind not in types:
387 raise error.Abort(_('unknown subrepo type %s') % kind)
388
362 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
389 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
363 """return instance of the right subrepo class for subrepo in path"""
390 """return instance of the right subrepo class for subrepo in path"""
364 # subrepo inherently violates our import layering rules
391 # subrepo inherently violates our import layering rules
@@ -369,10 +396,10 b' def subrepo(ctx, path, allowwdir=False, '
369 from . import hg as h
396 from . import hg as h
370 hg = h
397 hg = h
371
398
372 pathutil.pathauditor(ctx.repo().root)(path)
399 repo = ctx.repo()
400 _auditsubrepopath(repo, path)
373 state = ctx.substate[path]
401 state = ctx.substate[path]
374 if state[2] not in types:
402 _checktype(repo.ui, state[2])
375 raise error.Abort(_('unknown subrepo type %s') % state[2])
376 if allowwdir:
403 if allowwdir:
377 state = (state[0], ctx.subrev(path), state[2])
404 state = (state[0], ctx.subrev(path), state[2])
378 return types[state[2]](ctx, path, state[:2], allowcreate)
405 return types[state[2]](ctx, path, state[:2], allowcreate)
@@ -387,10 +414,10 b' def nullsubrepo(ctx, path, pctx):'
387 from . import hg as h
414 from . import hg as h
388 hg = h
415 hg = h
389
416
390 pathutil.pathauditor(ctx.repo().root)(path)
417 repo = ctx.repo()
418 _auditsubrepopath(repo, path)
391 state = ctx.substate[path]
419 state = ctx.substate[path]
392 if state[2] not in types:
420 _checktype(repo.ui, state[2])
393 raise error.Abort(_('unknown subrepo type %s') % state[2])
394 subrev = ''
421 subrev = ''
395 if state[2] == 'hg':
422 if state[2] == 'hg':
396 subrev = "0" * 40
423 subrev = "0" * 40
@@ -6,6 +6,10 b''
6 $ echo "autocrlf = false" >> $HOME/.gitconfig
6 $ echo "autocrlf = false" >> $HOME/.gitconfig
7 $ echo "[extensions]" >> $HGRCPATH
7 $ echo "[extensions]" >> $HGRCPATH
8 $ echo "convert=" >> $HGRCPATH
8 $ echo "convert=" >> $HGRCPATH
9 $ cat >> $HGRCPATH <<EOF
10 > [subrepos]
11 > git:allowed = true
12 > EOF
9 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
13 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
10 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
14 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
11 $ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
15 $ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
@@ -5,6 +5,9 b''
5 > mq =
5 > mq =
6 > [diff]
6 > [diff]
7 > nodates = 1
7 > nodates = 1
8 > [subrepos]
9 > allowed = true
10 > svn:allowed = true
8 > EOF
11 > EOF
9
12
10 fn to create new repository, and cd into it
13 fn to create new repository, and cd into it
@@ -41,7 +41,23 b' add subrepo clone'
41 $ echo 's = [git]../gitroot' > .hgsub
41 $ echo 's = [git]../gitroot' > .hgsub
42 $ git clone -q ../gitroot s
42 $ git clone -q ../gitroot s
43 $ hg add .hgsub
43 $ hg add .hgsub
44
45 git subrepo is disabled by default
46
44 $ hg commit -m 'new git subrepo'
47 $ hg commit -m 'new git subrepo'
48 abort: git subrepos not allowed
49 (see 'hg help config.subrepos' for details)
50 [255]
51
52 so enable it
53
54 $ cat >> $HGRCPATH <<EOF
55 > [subrepos]
56 > git:allowed = true
57 > EOF
58
59 $ hg commit -m 'new git subrepo'
60
45 $ hg debugsub
61 $ hg debugsub
46 path s
62 path s
47 source ../gitroot
63 source ../gitroot
@@ -86,9 +102,29 b' clone root'
86 path s
102 path s
87 source ../gitroot
103 source ../gitroot
88 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
104 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
105 $ cd ..
106
107 clone with subrepo disabled (update should fail)
108
109 $ hg clone t -U tc2 --config subrepos.allowed=false
110 $ hg update -R tc2 --config subrepos.allowed=false
111 abort: subrepos not enabled
112 (see 'hg help config.subrepos' for details)
113 [255]
114 $ ls tc2
115 a
116
117 $ hg clone t tc3 --config subrepos.allowed=false
118 updating to branch default
119 abort: subrepos not enabled
120 (see 'hg help config.subrepos' for details)
121 [255]
122 $ ls tc3
123 a
89
124
90 update to previous substate
125 update to previous substate
91
126
127 $ cd tc
92 $ hg update 1 -q
128 $ hg update 1 -q
93 $ cat s/g
129 $ cat s/g
94 g
130 g
@@ -400,11 +436,13 b" Don't crash if the subrepo is missing"
400 Don't crash if subrepo is a broken symlink
436 Don't crash if subrepo is a broken symlink
401 $ ln -s broken s
437 $ ln -s broken s
402 $ hg status -S
438 $ hg status -S
439 abort: subrepo 's' traverses symbolic link
440 [255]
403 $ hg push -q
441 $ hg push -q
404 abort: subrepo s is missing (in subrepository "s")
442 abort: subrepo 's' traverses symbolic link
405 [255]
443 [255]
406 $ hg commit --subrepos -qm missing
444 $ hg commit --subrepos -qm missing
407 abort: subrepo s is missing (in subrepository "s")
445 abort: subrepo 's' traverses symbolic link
408 [255]
446 [255]
409 $ rm s
447 $ rm s
410 #endif
448 #endif
@@ -57,6 +57,21 b' add first svn sub with leading whitespac'
57 $ mkdir subdir
57 $ mkdir subdir
58 $ svn co --quiet "$SVNREPOURL"/src subdir/s
58 $ svn co --quiet "$SVNREPOURL"/src subdir/s
59 $ hg add .hgsub
59 $ hg add .hgsub
60
61 svn subrepo is disabled by default
62
63 $ hg ci -m1
64 abort: svn subrepos not allowed
65 (see 'hg help config.subrepos' for details)
66 [255]
67
68 so enable it
69
70 $ cat >> $HGRCPATH <<EOF
71 > [subrepos]
72 > svn:allowed = true
73 > EOF
74
60 $ hg ci -m1
75 $ hg ci -m1
61
76
62 make sure we avoid empty commits (issue2445)
77 make sure we avoid empty commits (issue2445)
@@ -484,9 +484,47 b' clone'
484 path t
484 path t
485 source t
485 source t
486 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
486 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
487 $ cd ..
488
489 clone with subrepo disabled (update should fail)
490
491 $ hg clone t -U tc2 --config subrepos.allowed=false
492 $ hg update -R tc2 --config subrepos.allowed=false
493 abort: subrepos not enabled
494 (see 'hg help config.subrepos' for details)
495 [255]
496 $ ls tc2
497 a
498
499 $ hg clone t tc3 --config subrepos.allowed=false
500 updating to branch default
501 abort: subrepos not enabled
502 (see 'hg help config.subrepos' for details)
503 [255]
504 $ ls tc3
505 a
506
507 And again with just the hg type disabled
508
509 $ hg clone t -U tc4 --config subrepos.hg:allowed=false
510 $ hg update -R tc4 --config subrepos.hg:allowed=false
511 abort: hg subrepos not allowed
512 (see 'hg help config.subrepos' for details)
513 [255]
514 $ ls tc4
515 a
516
517 $ hg clone t tc5 --config subrepos.hg:allowed=false
518 updating to branch default
519 abort: hg subrepos not allowed
520 (see 'hg help config.subrepos' for details)
521 [255]
522 $ ls tc5
523 a
487
524
488 push
525 push
489
526
527 $ cd tc
490 $ echo bah > t/t
528 $ echo bah > t/t
491 $ hg ci -m11
529 $ hg ci -m11
492 committing subrepository t
530 committing subrepository t
General Comments 0
You need to be logged in to leave comments. Login now