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 |
@@ -817,6 +817,18 b" coreconfigitem('smtp', 'username'," | |||||
817 | coreconfigitem('sparse', 'missingwarning', |
|
817 | coreconfigitem('sparse', 'missingwarning', | |
818 | default=True, |
|
818 | default=True, | |
819 | ) |
|
819 | ) | |
|
820 | coreconfigitem('subrepos', 'allowed', | |||
|
821 | default=dynamicdefault, # to make backporting simpler | |||
|
822 | ) | |||
|
823 | coreconfigitem('subrepos', 'hg:allowed', | |||
|
824 | default=dynamicdefault, | |||
|
825 | ) | |||
|
826 | coreconfigitem('subrepos', 'git:allowed', | |||
|
827 | default=dynamicdefault, | |||
|
828 | ) | |||
|
829 | coreconfigitem('subrepos', 'svn:allowed', | |||
|
830 | default=dynamicdefault, | |||
|
831 | ) | |||
820 | coreconfigitem('templates', '.*', |
|
832 | coreconfigitem('templates', '.*', | |
821 | default=None, |
|
833 | default=None, | |
822 | generic=True, |
|
834 | 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 |
@@ -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