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' % |
|
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