##// END OF EJS Templates
subrepo: append subrepo path to subrepo error messages...
Angel Ezquerra -
r18109:9e3910db default
parent child Browse files
Show More
@@ -1,1281 +1,1325 b''
1 # subrepo.py - sub-repository handling for Mercurial
1 # subrepo.py - sub-repository handling for Mercurial
2 #
2 #
3 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import errno, os, re, xml.dom.minidom, shutil, posixpath
8 import errno, os, re, xml.dom.minidom, shutil, posixpath
9 import stat, subprocess, tarfile
9 import stat, subprocess, tarfile
10 from i18n import _
10 from i18n import _
11 import config, scmutil, util, node, error, cmdutil, bookmarks, match as matchmod
11 import config, scmutil, util, node, error, cmdutil, bookmarks, match as matchmod
12 hg = None
12 hg = None
13 propertycache = util.propertycache
13 propertycache = util.propertycache
14
14
15 nullstate = ('', '', 'empty')
15 nullstate = ('', '', 'empty')
16
16
17 class SubrepoAbort(error.Abort):
18 """Exception class used to avoid handling a subrepo error more than once"""
19
20 def annotatesubrepoerror(func):
21 def decoratedmethod(self, *args, **kargs):
22 try:
23 res = func(self, *args, **kargs)
24 except SubrepoAbort, ex:
25 # This exception has already been handled
26 raise ex
27 except error.Abort, ex:
28 errormsg = _('%s (in subrepo %s)') % (str(ex), subrelpath(self))
29 # avoid handling this exception by raising a SubrepoAbort exception
30 raise SubrepoAbort(errormsg, hint=ex.hint)
31 return res
32 return decoratedmethod
33
17 def state(ctx, ui):
34 def state(ctx, ui):
18 """return a state dict, mapping subrepo paths configured in .hgsub
35 """return a state dict, mapping subrepo paths configured in .hgsub
19 to tuple: (source from .hgsub, revision from .hgsubstate, kind
36 to tuple: (source from .hgsub, revision from .hgsubstate, kind
20 (key in types dict))
37 (key in types dict))
21 """
38 """
22 p = config.config()
39 p = config.config()
23 def read(f, sections=None, remap=None):
40 def read(f, sections=None, remap=None):
24 if f in ctx:
41 if f in ctx:
25 try:
42 try:
26 data = ctx[f].data()
43 data = ctx[f].data()
27 except IOError, err:
44 except IOError, err:
28 if err.errno != errno.ENOENT:
45 if err.errno != errno.ENOENT:
29 raise
46 raise
30 # handle missing subrepo spec files as removed
47 # handle missing subrepo spec files as removed
31 ui.warn(_("warning: subrepo spec file %s not found\n") % f)
48 ui.warn(_("warning: subrepo spec file %s not found\n") % f)
32 return
49 return
33 p.parse(f, data, sections, remap, read)
50 p.parse(f, data, sections, remap, read)
34 else:
51 else:
35 raise util.Abort(_("subrepo spec file %s not found") % f)
52 raise util.Abort(_("subrepo spec file %s not found") % f)
36
53
37 if '.hgsub' in ctx:
54 if '.hgsub' in ctx:
38 read('.hgsub')
55 read('.hgsub')
39
56
40 for path, src in ui.configitems('subpaths'):
57 for path, src in ui.configitems('subpaths'):
41 p.set('subpaths', path, src, ui.configsource('subpaths', path))
58 p.set('subpaths', path, src, ui.configsource('subpaths', path))
42
59
43 rev = {}
60 rev = {}
44 if '.hgsubstate' in ctx:
61 if '.hgsubstate' in ctx:
45 try:
62 try:
46 for i, l in enumerate(ctx['.hgsubstate'].data().splitlines()):
63 for i, l in enumerate(ctx['.hgsubstate'].data().splitlines()):
47 l = l.lstrip()
64 l = l.lstrip()
48 if not l:
65 if not l:
49 continue
66 continue
50 try:
67 try:
51 revision, path = l.split(" ", 1)
68 revision, path = l.split(" ", 1)
52 except ValueError:
69 except ValueError:
53 raise util.Abort(_("invalid subrepository revision "
70 raise util.Abort(_("invalid subrepository revision "
54 "specifier in .hgsubstate line %d")
71 "specifier in .hgsubstate line %d")
55 % (i + 1))
72 % (i + 1))
56 rev[path] = revision
73 rev[path] = revision
57 except IOError, err:
74 except IOError, err:
58 if err.errno != errno.ENOENT:
75 if err.errno != errno.ENOENT:
59 raise
76 raise
60
77
61 def remap(src):
78 def remap(src):
62 for pattern, repl in p.items('subpaths'):
79 for pattern, repl in p.items('subpaths'):
63 # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
80 # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
64 # does a string decode.
81 # does a string decode.
65 repl = repl.encode('string-escape')
82 repl = repl.encode('string-escape')
66 # However, we still want to allow back references to go
83 # However, we still want to allow back references to go
67 # through unharmed, so we turn r'\\1' into r'\1'. Again,
84 # through unharmed, so we turn r'\\1' into r'\1'. Again,
68 # extra escapes are needed because re.sub string decodes.
85 # extra escapes are needed because re.sub string decodes.
69 repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
86 repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
70 try:
87 try:
71 src = re.sub(pattern, repl, src, 1)
88 src = re.sub(pattern, repl, src, 1)
72 except re.error, e:
89 except re.error, e:
73 raise util.Abort(_("bad subrepository pattern in %s: %s")
90 raise util.Abort(_("bad subrepository pattern in %s: %s")
74 % (p.source('subpaths', pattern), e))
91 % (p.source('subpaths', pattern), e))
75 return src
92 return src
76
93
77 state = {}
94 state = {}
78 for path, src in p[''].items():
95 for path, src in p[''].items():
79 kind = 'hg'
96 kind = 'hg'
80 if src.startswith('['):
97 if src.startswith('['):
81 if ']' not in src:
98 if ']' not in src:
82 raise util.Abort(_('missing ] in subrepo source'))
99 raise util.Abort(_('missing ] in subrepo source'))
83 kind, src = src.split(']', 1)
100 kind, src = src.split(']', 1)
84 kind = kind[1:]
101 kind = kind[1:]
85 src = src.lstrip() # strip any extra whitespace after ']'
102 src = src.lstrip() # strip any extra whitespace after ']'
86
103
87 if not util.url(src).isabs():
104 if not util.url(src).isabs():
88 parent = _abssource(ctx._repo, abort=False)
105 parent = _abssource(ctx._repo, abort=False)
89 if parent:
106 if parent:
90 parent = util.url(parent)
107 parent = util.url(parent)
91 parent.path = posixpath.join(parent.path or '', src)
108 parent.path = posixpath.join(parent.path or '', src)
92 parent.path = posixpath.normpath(parent.path)
109 parent.path = posixpath.normpath(parent.path)
93 joined = str(parent)
110 joined = str(parent)
94 # Remap the full joined path and use it if it changes,
111 # Remap the full joined path and use it if it changes,
95 # else remap the original source.
112 # else remap the original source.
96 remapped = remap(joined)
113 remapped = remap(joined)
97 if remapped == joined:
114 if remapped == joined:
98 src = remap(src)
115 src = remap(src)
99 else:
116 else:
100 src = remapped
117 src = remapped
101
118
102 src = remap(src)
119 src = remap(src)
103 state[util.pconvert(path)] = (src.strip(), rev.get(path, ''), kind)
120 state[util.pconvert(path)] = (src.strip(), rev.get(path, ''), kind)
104
121
105 return state
122 return state
106
123
107 def writestate(repo, state):
124 def writestate(repo, state):
108 """rewrite .hgsubstate in (outer) repo with these subrepo states"""
125 """rewrite .hgsubstate in (outer) repo with these subrepo states"""
109 lines = ['%s %s\n' % (state[s][1], s) for s in sorted(state)]
126 lines = ['%s %s\n' % (state[s][1], s) for s in sorted(state)]
110 repo.wwrite('.hgsubstate', ''.join(lines), '')
127 repo.wwrite('.hgsubstate', ''.join(lines), '')
111
128
112 def submerge(repo, wctx, mctx, actx, overwrite):
129 def submerge(repo, wctx, mctx, actx, overwrite):
113 """delegated from merge.applyupdates: merging of .hgsubstate file
130 """delegated from merge.applyupdates: merging of .hgsubstate file
114 in working context, merging context and ancestor context"""
131 in working context, merging context and ancestor context"""
115 if mctx == actx: # backwards?
132 if mctx == actx: # backwards?
116 actx = wctx.p1()
133 actx = wctx.p1()
117 s1 = wctx.substate
134 s1 = wctx.substate
118 s2 = mctx.substate
135 s2 = mctx.substate
119 sa = actx.substate
136 sa = actx.substate
120 sm = {}
137 sm = {}
121
138
122 repo.ui.debug("subrepo merge %s %s %s\n" % (wctx, mctx, actx))
139 repo.ui.debug("subrepo merge %s %s %s\n" % (wctx, mctx, actx))
123
140
124 def debug(s, msg, r=""):
141 def debug(s, msg, r=""):
125 if r:
142 if r:
126 r = "%s:%s:%s" % r
143 r = "%s:%s:%s" % r
127 repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r))
144 repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r))
128
145
129 for s, l in s1.items():
146 for s, l in s1.items():
130 a = sa.get(s, nullstate)
147 a = sa.get(s, nullstate)
131 ld = l # local state with possible dirty flag for compares
148 ld = l # local state with possible dirty flag for compares
132 if wctx.sub(s).dirty():
149 if wctx.sub(s).dirty():
133 ld = (l[0], l[1] + "+")
150 ld = (l[0], l[1] + "+")
134 if wctx == actx: # overwrite
151 if wctx == actx: # overwrite
135 a = ld
152 a = ld
136
153
137 if s in s2:
154 if s in s2:
138 r = s2[s]
155 r = s2[s]
139 if ld == r or r == a: # no change or local is newer
156 if ld == r or r == a: # no change or local is newer
140 sm[s] = l
157 sm[s] = l
141 continue
158 continue
142 elif ld == a: # other side changed
159 elif ld == a: # other side changed
143 debug(s, "other changed, get", r)
160 debug(s, "other changed, get", r)
144 wctx.sub(s).get(r, overwrite)
161 wctx.sub(s).get(r, overwrite)
145 sm[s] = r
162 sm[s] = r
146 elif ld[0] != r[0]: # sources differ
163 elif ld[0] != r[0]: # sources differ
147 if repo.ui.promptchoice(
164 if repo.ui.promptchoice(
148 _(' subrepository sources for %s differ\n'
165 _(' subrepository sources for %s differ\n'
149 'use (l)ocal source (%s) or (r)emote source (%s)?')
166 'use (l)ocal source (%s) or (r)emote source (%s)?')
150 % (s, l[0], r[0]),
167 % (s, l[0], r[0]),
151 (_('&Local'), _('&Remote')), 0):
168 (_('&Local'), _('&Remote')), 0):
152 debug(s, "prompt changed, get", r)
169 debug(s, "prompt changed, get", r)
153 wctx.sub(s).get(r, overwrite)
170 wctx.sub(s).get(r, overwrite)
154 sm[s] = r
171 sm[s] = r
155 elif ld[1] == a[1]: # local side is unchanged
172 elif ld[1] == a[1]: # local side is unchanged
156 debug(s, "other side changed, get", r)
173 debug(s, "other side changed, get", r)
157 wctx.sub(s).get(r, overwrite)
174 wctx.sub(s).get(r, overwrite)
158 sm[s] = r
175 sm[s] = r
159 else:
176 else:
160 debug(s, "both sides changed, merge with", r)
177 debug(s, "both sides changed, merge with", r)
161 wctx.sub(s).merge(r)
178 wctx.sub(s).merge(r)
162 sm[s] = l
179 sm[s] = l
163 elif ld == a: # remote removed, local unchanged
180 elif ld == a: # remote removed, local unchanged
164 debug(s, "remote removed, remove")
181 debug(s, "remote removed, remove")
165 wctx.sub(s).remove()
182 wctx.sub(s).remove()
166 elif a == nullstate: # not present in remote or ancestor
183 elif a == nullstate: # not present in remote or ancestor
167 debug(s, "local added, keep")
184 debug(s, "local added, keep")
168 sm[s] = l
185 sm[s] = l
169 continue
186 continue
170 else:
187 else:
171 if repo.ui.promptchoice(
188 if repo.ui.promptchoice(
172 _(' local changed subrepository %s which remote removed\n'
189 _(' local changed subrepository %s which remote removed\n'
173 'use (c)hanged version or (d)elete?') % s,
190 'use (c)hanged version or (d)elete?') % s,
174 (_('&Changed'), _('&Delete')), 0):
191 (_('&Changed'), _('&Delete')), 0):
175 debug(s, "prompt remove")
192 debug(s, "prompt remove")
176 wctx.sub(s).remove()
193 wctx.sub(s).remove()
177
194
178 for s, r in sorted(s2.items()):
195 for s, r in sorted(s2.items()):
179 if s in s1:
196 if s in s1:
180 continue
197 continue
181 elif s not in sa:
198 elif s not in sa:
182 debug(s, "remote added, get", r)
199 debug(s, "remote added, get", r)
183 mctx.sub(s).get(r)
200 mctx.sub(s).get(r)
184 sm[s] = r
201 sm[s] = r
185 elif r != sa[s]:
202 elif r != sa[s]:
186 if repo.ui.promptchoice(
203 if repo.ui.promptchoice(
187 _(' remote changed subrepository %s which local removed\n'
204 _(' remote changed subrepository %s which local removed\n'
188 'use (c)hanged version or (d)elete?') % s,
205 'use (c)hanged version or (d)elete?') % s,
189 (_('&Changed'), _('&Delete')), 0) == 0:
206 (_('&Changed'), _('&Delete')), 0) == 0:
190 debug(s, "prompt recreate", r)
207 debug(s, "prompt recreate", r)
191 wctx.sub(s).get(r)
208 wctx.sub(s).get(r)
192 sm[s] = r
209 sm[s] = r
193
210
194 # record merged .hgsubstate
211 # record merged .hgsubstate
195 writestate(repo, sm)
212 writestate(repo, sm)
196
213
197 def _updateprompt(ui, sub, dirty, local, remote):
214 def _updateprompt(ui, sub, dirty, local, remote):
198 if dirty:
215 if dirty:
199 msg = (_(' subrepository sources for %s differ\n'
216 msg = (_(' subrepository sources for %s differ\n'
200 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
217 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
201 % (subrelpath(sub), local, remote))
218 % (subrelpath(sub), local, remote))
202 else:
219 else:
203 msg = (_(' subrepository sources for %s differ (in checked out '
220 msg = (_(' subrepository sources for %s differ (in checked out '
204 'version)\n'
221 'version)\n'
205 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
222 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
206 % (subrelpath(sub), local, remote))
223 % (subrelpath(sub), local, remote))
207 return ui.promptchoice(msg, (_('&Local'), _('&Remote')), 0)
224 return ui.promptchoice(msg, (_('&Local'), _('&Remote')), 0)
208
225
209 def reporelpath(repo):
226 def reporelpath(repo):
210 """return path to this (sub)repo as seen from outermost repo"""
227 """return path to this (sub)repo as seen from outermost repo"""
211 parent = repo
228 parent = repo
212 while util.safehasattr(parent, '_subparent'):
229 while util.safehasattr(parent, '_subparent'):
213 parent = parent._subparent
230 parent = parent._subparent
214 p = parent.root.rstrip(os.sep)
231 p = parent.root.rstrip(os.sep)
215 return repo.root[len(p) + 1:]
232 return repo.root[len(p) + 1:]
216
233
217 def subrelpath(sub):
234 def subrelpath(sub):
218 """return path to this subrepo as seen from outermost repo"""
235 """return path to this subrepo as seen from outermost repo"""
219 if util.safehasattr(sub, '_relpath'):
236 if util.safehasattr(sub, '_relpath'):
220 return sub._relpath
237 return sub._relpath
221 if not util.safehasattr(sub, '_repo'):
238 if not util.safehasattr(sub, '_repo'):
222 return sub._path
239 return sub._path
223 return reporelpath(sub._repo)
240 return reporelpath(sub._repo)
224
241
225 def _abssource(repo, push=False, abort=True):
242 def _abssource(repo, push=False, abort=True):
226 """return pull/push path of repo - either based on parent repo .hgsub info
243 """return pull/push path of repo - either based on parent repo .hgsub info
227 or on the top repo config. Abort or return None if no source found."""
244 or on the top repo config. Abort or return None if no source found."""
228 if util.safehasattr(repo, '_subparent'):
245 if util.safehasattr(repo, '_subparent'):
229 source = util.url(repo._subsource)
246 source = util.url(repo._subsource)
230 if source.isabs():
247 if source.isabs():
231 return str(source)
248 return str(source)
232 source.path = posixpath.normpath(source.path)
249 source.path = posixpath.normpath(source.path)
233 parent = _abssource(repo._subparent, push, abort=False)
250 parent = _abssource(repo._subparent, push, abort=False)
234 if parent:
251 if parent:
235 parent = util.url(util.pconvert(parent))
252 parent = util.url(util.pconvert(parent))
236 parent.path = posixpath.join(parent.path or '', source.path)
253 parent.path = posixpath.join(parent.path or '', source.path)
237 parent.path = posixpath.normpath(parent.path)
254 parent.path = posixpath.normpath(parent.path)
238 return str(parent)
255 return str(parent)
239 else: # recursion reached top repo
256 else: # recursion reached top repo
240 if util.safehasattr(repo, '_subtoppath'):
257 if util.safehasattr(repo, '_subtoppath'):
241 return repo._subtoppath
258 return repo._subtoppath
242 if push and repo.ui.config('paths', 'default-push'):
259 if push and repo.ui.config('paths', 'default-push'):
243 return repo.ui.config('paths', 'default-push')
260 return repo.ui.config('paths', 'default-push')
244 if repo.ui.config('paths', 'default'):
261 if repo.ui.config('paths', 'default'):
245 return repo.ui.config('paths', 'default')
262 return repo.ui.config('paths', 'default')
246 if abort:
263 if abort:
247 raise util.Abort(_("default path for subrepository %s not found") %
264 raise util.Abort(_("default path for subrepository not found"))
248 reporelpath(repo))
249
265
250 def itersubrepos(ctx1, ctx2):
266 def itersubrepos(ctx1, ctx2):
251 """find subrepos in ctx1 or ctx2"""
267 """find subrepos in ctx1 or ctx2"""
252 # Create a (subpath, ctx) mapping where we prefer subpaths from
268 # Create a (subpath, ctx) mapping where we prefer subpaths from
253 # ctx1. The subpaths from ctx2 are important when the .hgsub file
269 # ctx1. The subpaths from ctx2 are important when the .hgsub file
254 # has been modified (in ctx2) but not yet committed (in ctx1).
270 # has been modified (in ctx2) but not yet committed (in ctx1).
255 subpaths = dict.fromkeys(ctx2.substate, ctx2)
271 subpaths = dict.fromkeys(ctx2.substate, ctx2)
256 subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
272 subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
257 for subpath, ctx in sorted(subpaths.iteritems()):
273 for subpath, ctx in sorted(subpaths.iteritems()):
258 yield subpath, ctx.sub(subpath)
274 yield subpath, ctx.sub(subpath)
259
275
260 def subrepo(ctx, path):
276 def subrepo(ctx, path):
261 """return instance of the right subrepo class for subrepo in path"""
277 """return instance of the right subrepo class for subrepo in path"""
262 # subrepo inherently violates our import layering rules
278 # subrepo inherently violates our import layering rules
263 # because it wants to make repo objects from deep inside the stack
279 # because it wants to make repo objects from deep inside the stack
264 # so we manually delay the circular imports to not break
280 # so we manually delay the circular imports to not break
265 # scripts that don't use our demand-loading
281 # scripts that don't use our demand-loading
266 global hg
282 global hg
267 import hg as h
283 import hg as h
268 hg = h
284 hg = h
269
285
270 scmutil.pathauditor(ctx._repo.root)(path)
286 scmutil.pathauditor(ctx._repo.root)(path)
271 state = ctx.substate[path]
287 state = ctx.substate[path]
272 if state[2] not in types:
288 if state[2] not in types:
273 raise util.Abort(_('unknown subrepo type %s') % state[2])
289 raise util.Abort(_('unknown subrepo type %s') % state[2])
274 return types[state[2]](ctx, path, state[:2])
290 return types[state[2]](ctx, path, state[:2])
275
291
276 # subrepo classes need to implement the following abstract class:
292 # subrepo classes need to implement the following abstract class:
277
293
278 class abstractsubrepo(object):
294 class abstractsubrepo(object):
279
295
280 def dirty(self, ignoreupdate=False):
296 def dirty(self, ignoreupdate=False):
281 """returns true if the dirstate of the subrepo is dirty or does not
297 """returns true if the dirstate of the subrepo is dirty or does not
282 match current stored state. If ignoreupdate is true, only check
298 match current stored state. If ignoreupdate is true, only check
283 whether the subrepo has uncommitted changes in its dirstate.
299 whether the subrepo has uncommitted changes in its dirstate.
284 """
300 """
285 raise NotImplementedError
301 raise NotImplementedError
286
302
287 def basestate(self):
303 def basestate(self):
288 """current working directory base state, disregarding .hgsubstate
304 """current working directory base state, disregarding .hgsubstate
289 state and working directory modifications"""
305 state and working directory modifications"""
290 raise NotImplementedError
306 raise NotImplementedError
291
307
292 def checknested(self, path):
308 def checknested(self, path):
293 """check if path is a subrepository within this repository"""
309 """check if path is a subrepository within this repository"""
294 return False
310 return False
295
311
296 def commit(self, text, user, date):
312 def commit(self, text, user, date):
297 """commit the current changes to the subrepo with the given
313 """commit the current changes to the subrepo with the given
298 log message. Use given user and date if possible. Return the
314 log message. Use given user and date if possible. Return the
299 new state of the subrepo.
315 new state of the subrepo.
300 """
316 """
301 raise NotImplementedError
317 raise NotImplementedError
302
318
303 def remove(self):
319 def remove(self):
304 """remove the subrepo
320 """remove the subrepo
305
321
306 (should verify the dirstate is not dirty first)
322 (should verify the dirstate is not dirty first)
307 """
323 """
308 raise NotImplementedError
324 raise NotImplementedError
309
325
310 def get(self, state, overwrite=False):
326 def get(self, state, overwrite=False):
311 """run whatever commands are needed to put the subrepo into
327 """run whatever commands are needed to put the subrepo into
312 this state
328 this state
313 """
329 """
314 raise NotImplementedError
330 raise NotImplementedError
315
331
316 def merge(self, state):
332 def merge(self, state):
317 """merge currently-saved state with the new state."""
333 """merge currently-saved state with the new state."""
318 raise NotImplementedError
334 raise NotImplementedError
319
335
320 def push(self, opts):
336 def push(self, opts):
321 """perform whatever action is analogous to 'hg push'
337 """perform whatever action is analogous to 'hg push'
322
338
323 This may be a no-op on some systems.
339 This may be a no-op on some systems.
324 """
340 """
325 raise NotImplementedError
341 raise NotImplementedError
326
342
327 def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
343 def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
328 return []
344 return []
329
345
330 def status(self, rev2, **opts):
346 def status(self, rev2, **opts):
331 return [], [], [], [], [], [], []
347 return [], [], [], [], [], [], []
332
348
333 def diff(self, ui, diffopts, node2, match, prefix, **opts):
349 def diff(self, ui, diffopts, node2, match, prefix, **opts):
334 pass
350 pass
335
351
336 def outgoing(self, ui, dest, opts):
352 def outgoing(self, ui, dest, opts):
337 return 1
353 return 1
338
354
339 def incoming(self, ui, source, opts):
355 def incoming(self, ui, source, opts):
340 return 1
356 return 1
341
357
342 def files(self):
358 def files(self):
343 """return filename iterator"""
359 """return filename iterator"""
344 raise NotImplementedError
360 raise NotImplementedError
345
361
346 def filedata(self, name):
362 def filedata(self, name):
347 """return file data"""
363 """return file data"""
348 raise NotImplementedError
364 raise NotImplementedError
349
365
350 def fileflags(self, name):
366 def fileflags(self, name):
351 """return file flags"""
367 """return file flags"""
352 return ''
368 return ''
353
369
354 def archive(self, ui, archiver, prefix, match=None):
370 def archive(self, ui, archiver, prefix, match=None):
355 if match is not None:
371 if match is not None:
356 files = [f for f in self.files() if match(f)]
372 files = [f for f in self.files() if match(f)]
357 else:
373 else:
358 files = self.files()
374 files = self.files()
359 total = len(files)
375 total = len(files)
360 relpath = subrelpath(self)
376 relpath = subrelpath(self)
361 ui.progress(_('archiving (%s)') % relpath, 0,
377 ui.progress(_('archiving (%s)') % relpath, 0,
362 unit=_('files'), total=total)
378 unit=_('files'), total=total)
363 for i, name in enumerate(files):
379 for i, name in enumerate(files):
364 flags = self.fileflags(name)
380 flags = self.fileflags(name)
365 mode = 'x' in flags and 0755 or 0644
381 mode = 'x' in flags and 0755 or 0644
366 symlink = 'l' in flags
382 symlink = 'l' in flags
367 archiver.addfile(os.path.join(prefix, self._path, name),
383 archiver.addfile(os.path.join(prefix, self._path, name),
368 mode, symlink, self.filedata(name))
384 mode, symlink, self.filedata(name))
369 ui.progress(_('archiving (%s)') % relpath, i + 1,
385 ui.progress(_('archiving (%s)') % relpath, i + 1,
370 unit=_('files'), total=total)
386 unit=_('files'), total=total)
371 ui.progress(_('archiving (%s)') % relpath, None)
387 ui.progress(_('archiving (%s)') % relpath, None)
372
388
373 def walk(self, match):
389 def walk(self, match):
374 '''
390 '''
375 walk recursively through the directory tree, finding all files
391 walk recursively through the directory tree, finding all files
376 matched by the match function
392 matched by the match function
377 '''
393 '''
378 pass
394 pass
379
395
380 def forget(self, ui, match, prefix):
396 def forget(self, ui, match, prefix):
381 return ([], [])
397 return ([], [])
382
398
383 def revert(self, ui, substate, *pats, **opts):
399 def revert(self, ui, substate, *pats, **opts):
384 ui.warn('%s: reverting %s subrepos is unsupported\n' \
400 ui.warn('%s: reverting %s subrepos is unsupported\n' \
385 % (substate[0], substate[2]))
401 % (substate[0], substate[2]))
386 return []
402 return []
387
403
388 class hgsubrepo(abstractsubrepo):
404 class hgsubrepo(abstractsubrepo):
389 def __init__(self, ctx, path, state):
405 def __init__(self, ctx, path, state):
390 self._path = path
406 self._path = path
391 self._state = state
407 self._state = state
392 r = ctx._repo
408 r = ctx._repo
393 root = r.wjoin(path)
409 root = r.wjoin(path)
394 create = False
410 create = False
395 if not os.path.exists(os.path.join(root, '.hg')):
411 if not os.path.exists(os.path.join(root, '.hg')):
396 create = True
412 create = True
397 util.makedirs(root)
413 util.makedirs(root)
398 self._repo = hg.repository(r.baseui, root, create=create)
414 self._repo = hg.repository(r.baseui, root, create=create)
399 for s, k in [('ui', 'commitsubrepos')]:
415 for s, k in [('ui', 'commitsubrepos')]:
400 v = r.ui.config(s, k)
416 v = r.ui.config(s, k)
401 if v:
417 if v:
402 self._repo.ui.setconfig(s, k, v)
418 self._repo.ui.setconfig(s, k, v)
403 self._initrepo(r, state[0], create)
419 self._initrepo(r, state[0], create)
404
420
421 @annotatesubrepoerror
405 def _initrepo(self, parentrepo, source, create):
422 def _initrepo(self, parentrepo, source, create):
406 self._repo._subparent = parentrepo
423 self._repo._subparent = parentrepo
407 self._repo._subsource = source
424 self._repo._subsource = source
408
425
409 if create:
426 if create:
410 fp = self._repo.opener("hgrc", "w", text=True)
427 fp = self._repo.opener("hgrc", "w", text=True)
411 fp.write('[paths]\n')
428 fp.write('[paths]\n')
412
429
413 def addpathconfig(key, value):
430 def addpathconfig(key, value):
414 if value:
431 if value:
415 fp.write('%s = %s\n' % (key, value))
432 fp.write('%s = %s\n' % (key, value))
416 self._repo.ui.setconfig('paths', key, value)
433 self._repo.ui.setconfig('paths', key, value)
417
434
418 defpath = _abssource(self._repo, abort=False)
435 defpath = _abssource(self._repo, abort=False)
419 defpushpath = _abssource(self._repo, True, abort=False)
436 defpushpath = _abssource(self._repo, True, abort=False)
420 addpathconfig('default', defpath)
437 addpathconfig('default', defpath)
421 if defpath != defpushpath:
438 if defpath != defpushpath:
422 addpathconfig('default-push', defpushpath)
439 addpathconfig('default-push', defpushpath)
423 fp.close()
440 fp.close()
424
441
442 @annotatesubrepoerror
425 def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
443 def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
426 return cmdutil.add(ui, self._repo, match, dryrun, listsubrepos,
444 return cmdutil.add(ui, self._repo, match, dryrun, listsubrepos,
427 os.path.join(prefix, self._path), explicitonly)
445 os.path.join(prefix, self._path), explicitonly)
428
446
447 @annotatesubrepoerror
429 def status(self, rev2, **opts):
448 def status(self, rev2, **opts):
430 try:
449 try:
431 rev1 = self._state[1]
450 rev1 = self._state[1]
432 ctx1 = self._repo[rev1]
451 ctx1 = self._repo[rev1]
433 ctx2 = self._repo[rev2]
452 ctx2 = self._repo[rev2]
434 return self._repo.status(ctx1, ctx2, **opts)
453 return self._repo.status(ctx1, ctx2, **opts)
435 except error.RepoLookupError, inst:
454 except error.RepoLookupError, inst:
436 self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
455 self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
437 % (inst, subrelpath(self)))
456 % (inst, subrelpath(self)))
438 return [], [], [], [], [], [], []
457 return [], [], [], [], [], [], []
439
458
459 @annotatesubrepoerror
440 def diff(self, ui, diffopts, node2, match, prefix, **opts):
460 def diff(self, ui, diffopts, node2, match, prefix, **opts):
441 try:
461 try:
442 node1 = node.bin(self._state[1])
462 node1 = node.bin(self._state[1])
443 # We currently expect node2 to come from substate and be
463 # We currently expect node2 to come from substate and be
444 # in hex format
464 # in hex format
445 if node2 is not None:
465 if node2 is not None:
446 node2 = node.bin(node2)
466 node2 = node.bin(node2)
447 cmdutil.diffordiffstat(ui, self._repo, diffopts,
467 cmdutil.diffordiffstat(ui, self._repo, diffopts,
448 node1, node2, match,
468 node1, node2, match,
449 prefix=posixpath.join(prefix, self._path),
469 prefix=posixpath.join(prefix, self._path),
450 listsubrepos=True, **opts)
470 listsubrepos=True, **opts)
451 except error.RepoLookupError, inst:
471 except error.RepoLookupError, inst:
452 self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
472 self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
453 % (inst, subrelpath(self)))
473 % (inst, subrelpath(self)))
454
474
475 @annotatesubrepoerror
455 def archive(self, ui, archiver, prefix, match=None):
476 def archive(self, ui, archiver, prefix, match=None):
456 self._get(self._state + ('hg',))
477 self._get(self._state + ('hg',))
457 abstractsubrepo.archive(self, ui, archiver, prefix, match)
478 abstractsubrepo.archive(self, ui, archiver, prefix, match)
458
479
459 rev = self._state[1]
480 rev = self._state[1]
460 ctx = self._repo[rev]
481 ctx = self._repo[rev]
461 for subpath in ctx.substate:
482 for subpath in ctx.substate:
462 s = subrepo(ctx, subpath)
483 s = subrepo(ctx, subpath)
463 submatch = matchmod.narrowmatcher(subpath, match)
484 submatch = matchmod.narrowmatcher(subpath, match)
464 s.archive(ui, archiver, os.path.join(prefix, self._path), submatch)
485 s.archive(ui, archiver, os.path.join(prefix, self._path), submatch)
465
486
487 @annotatesubrepoerror
466 def dirty(self, ignoreupdate=False):
488 def dirty(self, ignoreupdate=False):
467 r = self._state[1]
489 r = self._state[1]
468 if r == '' and not ignoreupdate: # no state recorded
490 if r == '' and not ignoreupdate: # no state recorded
469 return True
491 return True
470 w = self._repo[None]
492 w = self._repo[None]
471 if r != w.p1().hex() and not ignoreupdate:
493 if r != w.p1().hex() and not ignoreupdate:
472 # different version checked out
494 # different version checked out
473 return True
495 return True
474 return w.dirty() # working directory changed
496 return w.dirty() # working directory changed
475
497
476 def basestate(self):
498 def basestate(self):
477 return self._repo['.'].hex()
499 return self._repo['.'].hex()
478
500
479 def checknested(self, path):
501 def checknested(self, path):
480 return self._repo._checknested(self._repo.wjoin(path))
502 return self._repo._checknested(self._repo.wjoin(path))
481
503
504 @annotatesubrepoerror
482 def commit(self, text, user, date):
505 def commit(self, text, user, date):
483 # don't bother committing in the subrepo if it's only been
506 # don't bother committing in the subrepo if it's only been
484 # updated
507 # updated
485 if not self.dirty(True):
508 if not self.dirty(True):
486 return self._repo['.'].hex()
509 return self._repo['.'].hex()
487 self._repo.ui.debug("committing subrepo %s\n" % subrelpath(self))
510 self._repo.ui.debug("committing subrepo %s\n" % subrelpath(self))
488 n = self._repo.commit(text, user, date)
511 n = self._repo.commit(text, user, date)
489 if not n:
512 if not n:
490 return self._repo['.'].hex() # different version checked out
513 return self._repo['.'].hex() # different version checked out
491 return node.hex(n)
514 return node.hex(n)
492
515
516 @annotatesubrepoerror
493 def remove(self):
517 def remove(self):
494 # we can't fully delete the repository as it may contain
518 # we can't fully delete the repository as it may contain
495 # local-only history
519 # local-only history
496 self._repo.ui.note(_('removing subrepo %s\n') % subrelpath(self))
520 self._repo.ui.note(_('removing subrepo %s\n') % subrelpath(self))
497 hg.clean(self._repo, node.nullid, False)
521 hg.clean(self._repo, node.nullid, False)
498
522
499 def _get(self, state):
523 def _get(self, state):
500 source, revision, kind = state
524 source, revision, kind = state
501 if revision not in self._repo:
525 if revision not in self._repo:
502 self._repo._subsource = source
526 self._repo._subsource = source
503 srcurl = _abssource(self._repo)
527 srcurl = _abssource(self._repo)
504 other = hg.peer(self._repo, {}, srcurl)
528 other = hg.peer(self._repo, {}, srcurl)
505 if len(self._repo) == 0:
529 if len(self._repo) == 0:
506 self._repo.ui.status(_('cloning subrepo %s from %s\n')
530 self._repo.ui.status(_('cloning subrepo %s from %s\n')
507 % (subrelpath(self), srcurl))
531 % (subrelpath(self), srcurl))
508 parentrepo = self._repo._subparent
532 parentrepo = self._repo._subparent
509 shutil.rmtree(self._repo.path)
533 shutil.rmtree(self._repo.path)
510 other, cloned = hg.clone(self._repo._subparent.baseui, {},
534 other, cloned = hg.clone(self._repo._subparent.baseui, {},
511 other, self._repo.root,
535 other, self._repo.root,
512 update=False)
536 update=False)
513 self._repo = cloned.local()
537 self._repo = cloned.local()
514 self._initrepo(parentrepo, source, create=True)
538 self._initrepo(parentrepo, source, create=True)
515 else:
539 else:
516 self._repo.ui.status(_('pulling subrepo %s from %s\n')
540 self._repo.ui.status(_('pulling subrepo %s from %s\n')
517 % (subrelpath(self), srcurl))
541 % (subrelpath(self), srcurl))
518 self._repo.pull(other)
542 self._repo.pull(other)
519 bookmarks.updatefromremote(self._repo.ui, self._repo, other,
543 bookmarks.updatefromremote(self._repo.ui, self._repo, other,
520 srcurl)
544 srcurl)
521
545
546 @annotatesubrepoerror
522 def get(self, state, overwrite=False):
547 def get(self, state, overwrite=False):
523 self._get(state)
548 self._get(state)
524 source, revision, kind = state
549 source, revision, kind = state
525 self._repo.ui.debug("getting subrepo %s\n" % self._path)
550 self._repo.ui.debug("getting subrepo %s\n" % self._path)
526 hg.updaterepo(self._repo, revision, overwrite)
551 hg.updaterepo(self._repo, revision, overwrite)
527
552
553 @annotatesubrepoerror
528 def merge(self, state):
554 def merge(self, state):
529 self._get(state)
555 self._get(state)
530 cur = self._repo['.']
556 cur = self._repo['.']
531 dst = self._repo[state[1]]
557 dst = self._repo[state[1]]
532 anc = dst.ancestor(cur)
558 anc = dst.ancestor(cur)
533
559
534 def mergefunc():
560 def mergefunc():
535 if anc == cur and dst.branch() == cur.branch():
561 if anc == cur and dst.branch() == cur.branch():
536 self._repo.ui.debug("updating subrepo %s\n" % subrelpath(self))
562 self._repo.ui.debug("updating subrepo %s\n" % subrelpath(self))
537 hg.update(self._repo, state[1])
563 hg.update(self._repo, state[1])
538 elif anc == dst:
564 elif anc == dst:
539 self._repo.ui.debug("skipping subrepo %s\n" % subrelpath(self))
565 self._repo.ui.debug("skipping subrepo %s\n" % subrelpath(self))
540 else:
566 else:
541 self._repo.ui.debug("merging subrepo %s\n" % subrelpath(self))
567 self._repo.ui.debug("merging subrepo %s\n" % subrelpath(self))
542 hg.merge(self._repo, state[1], remind=False)
568 hg.merge(self._repo, state[1], remind=False)
543
569
544 wctx = self._repo[None]
570 wctx = self._repo[None]
545 if self.dirty():
571 if self.dirty():
546 if anc != dst:
572 if anc != dst:
547 if _updateprompt(self._repo.ui, self, wctx.dirty(), cur, dst):
573 if _updateprompt(self._repo.ui, self, wctx.dirty(), cur, dst):
548 mergefunc()
574 mergefunc()
549 else:
575 else:
550 mergefunc()
576 mergefunc()
551 else:
577 else:
552 mergefunc()
578 mergefunc()
553
579
580 @annotatesubrepoerror
554 def push(self, opts):
581 def push(self, opts):
555 force = opts.get('force')
582 force = opts.get('force')
556 newbranch = opts.get('new_branch')
583 newbranch = opts.get('new_branch')
557 ssh = opts.get('ssh')
584 ssh = opts.get('ssh')
558
585
559 # push subrepos depth-first for coherent ordering
586 # push subrepos depth-first for coherent ordering
560 c = self._repo['']
587 c = self._repo['']
561 subs = c.substate # only repos that are committed
588 subs = c.substate # only repos that are committed
562 for s in sorted(subs):
589 for s in sorted(subs):
563 if c.sub(s).push(opts) == 0:
590 if c.sub(s).push(opts) == 0:
564 return False
591 return False
565
592
566 dsturl = _abssource(self._repo, True)
593 dsturl = _abssource(self._repo, True)
567 self._repo.ui.status(_('pushing subrepo %s to %s\n') %
594 self._repo.ui.status(_('pushing subrepo %s to %s\n') %
568 (subrelpath(self), dsturl))
595 (subrelpath(self), dsturl))
569 other = hg.peer(self._repo, {'ssh': ssh}, dsturl)
596 other = hg.peer(self._repo, {'ssh': ssh}, dsturl)
570 return self._repo.push(other, force, newbranch=newbranch)
597 return self._repo.push(other, force, newbranch=newbranch)
571
598
599 @annotatesubrepoerror
572 def outgoing(self, ui, dest, opts):
600 def outgoing(self, ui, dest, opts):
573 return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts)
601 return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts)
574
602
603 @annotatesubrepoerror
575 def incoming(self, ui, source, opts):
604 def incoming(self, ui, source, opts):
576 return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts)
605 return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts)
577
606
607 @annotatesubrepoerror
578 def files(self):
608 def files(self):
579 rev = self._state[1]
609 rev = self._state[1]
580 ctx = self._repo[rev]
610 ctx = self._repo[rev]
581 return ctx.manifest()
611 return ctx.manifest()
582
612
583 def filedata(self, name):
613 def filedata(self, name):
584 rev = self._state[1]
614 rev = self._state[1]
585 return self._repo[rev][name].data()
615 return self._repo[rev][name].data()
586
616
587 def fileflags(self, name):
617 def fileflags(self, name):
588 rev = self._state[1]
618 rev = self._state[1]
589 ctx = self._repo[rev]
619 ctx = self._repo[rev]
590 return ctx.flags(name)
620 return ctx.flags(name)
591
621
592 def walk(self, match):
622 def walk(self, match):
593 ctx = self._repo[None]
623 ctx = self._repo[None]
594 return ctx.walk(match)
624 return ctx.walk(match)
595
625
626 @annotatesubrepoerror
596 def forget(self, ui, match, prefix):
627 def forget(self, ui, match, prefix):
597 return cmdutil.forget(ui, self._repo, match,
628 return cmdutil.forget(ui, self._repo, match,
598 os.path.join(prefix, self._path), True)
629 os.path.join(prefix, self._path), True)
599
630
631 @annotatesubrepoerror
600 def revert(self, ui, substate, *pats, **opts):
632 def revert(self, ui, substate, *pats, **opts):
601 # reverting a subrepo is a 2 step process:
633 # reverting a subrepo is a 2 step process:
602 # 1. if the no_backup is not set, revert all modified
634 # 1. if the no_backup is not set, revert all modified
603 # files inside the subrepo
635 # files inside the subrepo
604 # 2. update the subrepo to the revision specified in
636 # 2. update the subrepo to the revision specified in
605 # the corresponding substate dictionary
637 # the corresponding substate dictionary
606 ui.status(_('reverting subrepo %s\n') % substate[0])
638 ui.status(_('reverting subrepo %s\n') % substate[0])
607 if not opts.get('no_backup'):
639 if not opts.get('no_backup'):
608 # Revert all files on the subrepo, creating backups
640 # Revert all files on the subrepo, creating backups
609 # Note that this will not recursively revert subrepos
641 # Note that this will not recursively revert subrepos
610 # We could do it if there was a set:subrepos() predicate
642 # We could do it if there was a set:subrepos() predicate
611 opts = opts.copy()
643 opts = opts.copy()
612 opts['date'] = None
644 opts['date'] = None
613 opts['rev'] = substate[1]
645 opts['rev'] = substate[1]
614
646
615 pats = []
647 pats = []
616 if not opts['all']:
648 if not opts['all']:
617 pats = ['set:modified()']
649 pats = ['set:modified()']
618 self.filerevert(ui, *pats, **opts)
650 self.filerevert(ui, *pats, **opts)
619
651
620 # Update the repo to the revision specified in the given substate
652 # Update the repo to the revision specified in the given substate
621 self.get(substate, overwrite=True)
653 self.get(substate, overwrite=True)
622
654
623 def filerevert(self, ui, *pats, **opts):
655 def filerevert(self, ui, *pats, **opts):
624 ctx = self._repo[opts['rev']]
656 ctx = self._repo[opts['rev']]
625 parents = self._repo.dirstate.parents()
657 parents = self._repo.dirstate.parents()
626 if opts['all']:
658 if opts['all']:
627 pats = ['set:modified()']
659 pats = ['set:modified()']
628 else:
660 else:
629 pats = []
661 pats = []
630 cmdutil.revert(ui, self._repo, ctx, parents, *pats, **opts)
662 cmdutil.revert(ui, self._repo, ctx, parents, *pats, **opts)
631
663
632 class svnsubrepo(abstractsubrepo):
664 class svnsubrepo(abstractsubrepo):
633 def __init__(self, ctx, path, state):
665 def __init__(self, ctx, path, state):
634 self._path = path
666 self._path = path
635 self._state = state
667 self._state = state
636 self._ctx = ctx
668 self._ctx = ctx
637 self._ui = ctx._repo.ui
669 self._ui = ctx._repo.ui
638 self._exe = util.findexe('svn')
670 self._exe = util.findexe('svn')
639 if not self._exe:
671 if not self._exe:
640 raise util.Abort(_("'svn' executable not found for subrepo '%s'")
672 raise util.Abort(_("'svn' executable not found for subrepo '%s'")
641 % self._path)
673 % self._path)
642
674
643 def _svncommand(self, commands, filename='', failok=False):
675 def _svncommand(self, commands, filename='', failok=False):
644 cmd = [self._exe]
676 cmd = [self._exe]
645 extrakw = {}
677 extrakw = {}
646 if not self._ui.interactive():
678 if not self._ui.interactive():
647 # Making stdin be a pipe should prevent svn from behaving
679 # Making stdin be a pipe should prevent svn from behaving
648 # interactively even if we can't pass --non-interactive.
680 # interactively even if we can't pass --non-interactive.
649 extrakw['stdin'] = subprocess.PIPE
681 extrakw['stdin'] = subprocess.PIPE
650 # Starting in svn 1.5 --non-interactive is a global flag
682 # Starting in svn 1.5 --non-interactive is a global flag
651 # instead of being per-command, but we need to support 1.4 so
683 # instead of being per-command, but we need to support 1.4 so
652 # we have to be intelligent about what commands take
684 # we have to be intelligent about what commands take
653 # --non-interactive.
685 # --non-interactive.
654 if commands[0] in ('update', 'checkout', 'commit'):
686 if commands[0] in ('update', 'checkout', 'commit'):
655 cmd.append('--non-interactive')
687 cmd.append('--non-interactive')
656 cmd.extend(commands)
688 cmd.extend(commands)
657 if filename is not None:
689 if filename is not None:
658 path = os.path.join(self._ctx._repo.origroot, self._path, filename)
690 path = os.path.join(self._ctx._repo.origroot, self._path, filename)
659 cmd.append(path)
691 cmd.append(path)
660 env = dict(os.environ)
692 env = dict(os.environ)
661 # Avoid localized output, preserve current locale for everything else.
693 # Avoid localized output, preserve current locale for everything else.
662 lc_all = env.get('LC_ALL')
694 lc_all = env.get('LC_ALL')
663 if lc_all:
695 if lc_all:
664 env['LANG'] = lc_all
696 env['LANG'] = lc_all
665 del env['LC_ALL']
697 del env['LC_ALL']
666 env['LC_MESSAGES'] = 'C'
698 env['LC_MESSAGES'] = 'C'
667 p = subprocess.Popen(cmd, bufsize=-1, close_fds=util.closefds,
699 p = subprocess.Popen(cmd, bufsize=-1, close_fds=util.closefds,
668 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
700 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
669 universal_newlines=True, env=env, **extrakw)
701 universal_newlines=True, env=env, **extrakw)
670 stdout, stderr = p.communicate()
702 stdout, stderr = p.communicate()
671 stderr = stderr.strip()
703 stderr = stderr.strip()
672 if not failok:
704 if not failok:
673 if p.returncode:
705 if p.returncode:
674 raise util.Abort(stderr or 'exited with code %d' % p.returncode)
706 raise util.Abort(stderr or 'exited with code %d' % p.returncode)
675 if stderr:
707 if stderr:
676 self._ui.warn(stderr + '\n')
708 self._ui.warn(stderr + '\n')
677 return stdout, stderr
709 return stdout, stderr
678
710
679 @propertycache
711 @propertycache
680 def _svnversion(self):
712 def _svnversion(self):
681 output, err = self._svncommand(['--version', '--quiet'], filename=None)
713 output, err = self._svncommand(['--version', '--quiet'], filename=None)
682 m = re.search(r'^(\d+)\.(\d+)', output)
714 m = re.search(r'^(\d+)\.(\d+)', output)
683 if not m:
715 if not m:
684 raise util.Abort(_('cannot retrieve svn tool version'))
716 raise util.Abort(_('cannot retrieve svn tool version'))
685 return (int(m.group(1)), int(m.group(2)))
717 return (int(m.group(1)), int(m.group(2)))
686
718
687 def _wcrevs(self):
719 def _wcrevs(self):
688 # Get the working directory revision as well as the last
720 # Get the working directory revision as well as the last
689 # commit revision so we can compare the subrepo state with
721 # commit revision so we can compare the subrepo state with
690 # both. We used to store the working directory one.
722 # both. We used to store the working directory one.
691 output, err = self._svncommand(['info', '--xml'])
723 output, err = self._svncommand(['info', '--xml'])
692 doc = xml.dom.minidom.parseString(output)
724 doc = xml.dom.minidom.parseString(output)
693 entries = doc.getElementsByTagName('entry')
725 entries = doc.getElementsByTagName('entry')
694 lastrev, rev = '0', '0'
726 lastrev, rev = '0', '0'
695 if entries:
727 if entries:
696 rev = str(entries[0].getAttribute('revision')) or '0'
728 rev = str(entries[0].getAttribute('revision')) or '0'
697 commits = entries[0].getElementsByTagName('commit')
729 commits = entries[0].getElementsByTagName('commit')
698 if commits:
730 if commits:
699 lastrev = str(commits[0].getAttribute('revision')) or '0'
731 lastrev = str(commits[0].getAttribute('revision')) or '0'
700 return (lastrev, rev)
732 return (lastrev, rev)
701
733
702 def _wcrev(self):
734 def _wcrev(self):
703 return self._wcrevs()[0]
735 return self._wcrevs()[0]
704
736
705 def _wcchanged(self):
737 def _wcchanged(self):
706 """Return (changes, extchanges, missing) where changes is True
738 """Return (changes, extchanges, missing) where changes is True
707 if the working directory was changed, extchanges is
739 if the working directory was changed, extchanges is
708 True if any of these changes concern an external entry and missing
740 True if any of these changes concern an external entry and missing
709 is True if any change is a missing entry.
741 is True if any change is a missing entry.
710 """
742 """
711 output, err = self._svncommand(['status', '--xml'])
743 output, err = self._svncommand(['status', '--xml'])
712 externals, changes, missing = [], [], []
744 externals, changes, missing = [], [], []
713 doc = xml.dom.minidom.parseString(output)
745 doc = xml.dom.minidom.parseString(output)
714 for e in doc.getElementsByTagName('entry'):
746 for e in doc.getElementsByTagName('entry'):
715 s = e.getElementsByTagName('wc-status')
747 s = e.getElementsByTagName('wc-status')
716 if not s:
748 if not s:
717 continue
749 continue
718 item = s[0].getAttribute('item')
750 item = s[0].getAttribute('item')
719 props = s[0].getAttribute('props')
751 props = s[0].getAttribute('props')
720 path = e.getAttribute('path')
752 path = e.getAttribute('path')
721 if item == 'external':
753 if item == 'external':
722 externals.append(path)
754 externals.append(path)
723 elif item == 'missing':
755 elif item == 'missing':
724 missing.append(path)
756 missing.append(path)
725 if (item not in ('', 'normal', 'unversioned', 'external')
757 if (item not in ('', 'normal', 'unversioned', 'external')
726 or props not in ('', 'none', 'normal')):
758 or props not in ('', 'none', 'normal')):
727 changes.append(path)
759 changes.append(path)
728 for path in changes:
760 for path in changes:
729 for ext in externals:
761 for ext in externals:
730 if path == ext or path.startswith(ext + os.sep):
762 if path == ext or path.startswith(ext + os.sep):
731 return True, True, bool(missing)
763 return True, True, bool(missing)
732 return bool(changes), False, bool(missing)
764 return bool(changes), False, bool(missing)
733
765
734 def dirty(self, ignoreupdate=False):
766 def dirty(self, ignoreupdate=False):
735 if not self._wcchanged()[0]:
767 if not self._wcchanged()[0]:
736 if self._state[1] in self._wcrevs() or ignoreupdate:
768 if self._state[1] in self._wcrevs() or ignoreupdate:
737 return False
769 return False
738 return True
770 return True
739
771
740 def basestate(self):
772 def basestate(self):
741 lastrev, rev = self._wcrevs()
773 lastrev, rev = self._wcrevs()
742 if lastrev != rev:
774 if lastrev != rev:
743 # Last committed rev is not the same than rev. We would
775 # Last committed rev is not the same than rev. We would
744 # like to take lastrev but we do not know if the subrepo
776 # like to take lastrev but we do not know if the subrepo
745 # URL exists at lastrev. Test it and fallback to rev it
777 # URL exists at lastrev. Test it and fallback to rev it
746 # is not there.
778 # is not there.
747 try:
779 try:
748 self._svncommand(['list', '%s@%s' % (self._state[0], lastrev)])
780 self._svncommand(['list', '%s@%s' % (self._state[0], lastrev)])
749 return lastrev
781 return lastrev
750 except error.Abort:
782 except error.Abort:
751 pass
783 pass
752 return rev
784 return rev
753
785
786 @annotatesubrepoerror
754 def commit(self, text, user, date):
787 def commit(self, text, user, date):
755 # user and date are out of our hands since svn is centralized
788 # user and date are out of our hands since svn is centralized
756 changed, extchanged, missing = self._wcchanged()
789 changed, extchanged, missing = self._wcchanged()
757 if not changed:
790 if not changed:
758 return self.basestate()
791 return self.basestate()
759 if extchanged:
792 if extchanged:
760 # Do not try to commit externals
793 # Do not try to commit externals
761 raise util.Abort(_('cannot commit svn externals'))
794 raise util.Abort(_('cannot commit svn externals'))
762 if missing:
795 if missing:
763 # svn can commit with missing entries but aborting like hg
796 # svn can commit with missing entries but aborting like hg
764 # seems a better approach.
797 # seems a better approach.
765 raise util.Abort(_('cannot commit missing svn entries'))
798 raise util.Abort(_('cannot commit missing svn entries'))
766 commitinfo, err = self._svncommand(['commit', '-m', text])
799 commitinfo, err = self._svncommand(['commit', '-m', text])
767 self._ui.status(commitinfo)
800 self._ui.status(commitinfo)
768 newrev = re.search('Committed revision ([0-9]+).', commitinfo)
801 newrev = re.search('Committed revision ([0-9]+).', commitinfo)
769 if not newrev:
802 if not newrev:
770 if not commitinfo.strip():
803 if not commitinfo.strip():
771 # Sometimes, our definition of "changed" differs from
804 # Sometimes, our definition of "changed" differs from
772 # svn one. For instance, svn ignores missing files
805 # svn one. For instance, svn ignores missing files
773 # when committing. If there are only missing files, no
806 # when committing. If there are only missing files, no
774 # commit is made, no output and no error code.
807 # commit is made, no output and no error code.
775 raise util.Abort(_('failed to commit svn changes'))
808 raise util.Abort(_('failed to commit svn changes'))
776 raise util.Abort(commitinfo.splitlines()[-1])
809 raise util.Abort(commitinfo.splitlines()[-1])
777 newrev = newrev.groups()[0]
810 newrev = newrev.groups()[0]
778 self._ui.status(self._svncommand(['update', '-r', newrev])[0])
811 self._ui.status(self._svncommand(['update', '-r', newrev])[0])
779 return newrev
812 return newrev
780
813
814 @annotatesubrepoerror
781 def remove(self):
815 def remove(self):
782 if self.dirty():
816 if self.dirty():
783 self._ui.warn(_('not removing repo %s because '
817 self._ui.warn(_('not removing repo %s because '
784 'it has changes.\n' % self._path))
818 'it has changes.\n' % self._path))
785 return
819 return
786 self._ui.note(_('removing subrepo %s\n') % self._path)
820 self._ui.note(_('removing subrepo %s\n') % self._path)
787
821
788 def onerror(function, path, excinfo):
822 def onerror(function, path, excinfo):
789 if function is not os.remove:
823 if function is not os.remove:
790 raise
824 raise
791 # read-only files cannot be unlinked under Windows
825 # read-only files cannot be unlinked under Windows
792 s = os.stat(path)
826 s = os.stat(path)
793 if (s.st_mode & stat.S_IWRITE) != 0:
827 if (s.st_mode & stat.S_IWRITE) != 0:
794 raise
828 raise
795 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
829 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
796 os.remove(path)
830 os.remove(path)
797
831
798 path = self._ctx._repo.wjoin(self._path)
832 path = self._ctx._repo.wjoin(self._path)
799 shutil.rmtree(path, onerror=onerror)
833 shutil.rmtree(path, onerror=onerror)
800 try:
834 try:
801 os.removedirs(os.path.dirname(path))
835 os.removedirs(os.path.dirname(path))
802 except OSError:
836 except OSError:
803 pass
837 pass
804
838
839 @annotatesubrepoerror
805 def get(self, state, overwrite=False):
840 def get(self, state, overwrite=False):
806 if overwrite:
841 if overwrite:
807 self._svncommand(['revert', '--recursive'])
842 self._svncommand(['revert', '--recursive'])
808 args = ['checkout']
843 args = ['checkout']
809 if self._svnversion >= (1, 5):
844 if self._svnversion >= (1, 5):
810 args.append('--force')
845 args.append('--force')
811 # The revision must be specified at the end of the URL to properly
846 # The revision must be specified at the end of the URL to properly
812 # update to a directory which has since been deleted and recreated.
847 # update to a directory which has since been deleted and recreated.
813 args.append('%s@%s' % (state[0], state[1]))
848 args.append('%s@%s' % (state[0], state[1]))
814 status, err = self._svncommand(args, failok=True)
849 status, err = self._svncommand(args, failok=True)
815 if not re.search('Checked out revision [0-9]+.', status):
850 if not re.search('Checked out revision [0-9]+.', status):
816 if ('is already a working copy for a different URL' in err
851 if ('is already a working copy for a different URL' in err
817 and (self._wcchanged()[:2] == (False, False))):
852 and (self._wcchanged()[:2] == (False, False))):
818 # obstructed but clean working copy, so just blow it away.
853 # obstructed but clean working copy, so just blow it away.
819 self.remove()
854 self.remove()
820 self.get(state, overwrite=False)
855 self.get(state, overwrite=False)
821 return
856 return
822 raise util.Abort((status or err).splitlines()[-1])
857 raise util.Abort((status or err).splitlines()[-1])
823 self._ui.status(status)
858 self._ui.status(status)
824
859
860 @annotatesubrepoerror
825 def merge(self, state):
861 def merge(self, state):
826 old = self._state[1]
862 old = self._state[1]
827 new = state[1]
863 new = state[1]
828 wcrev = self._wcrev()
864 wcrev = self._wcrev()
829 if new != wcrev:
865 if new != wcrev:
830 dirty = old == wcrev or self._wcchanged()[0]
866 dirty = old == wcrev or self._wcchanged()[0]
831 if _updateprompt(self._ui, self, dirty, wcrev, new):
867 if _updateprompt(self._ui, self, dirty, wcrev, new):
832 self.get(state, False)
868 self.get(state, False)
833
869
834 def push(self, opts):
870 def push(self, opts):
835 # push is a no-op for SVN
871 # push is a no-op for SVN
836 return True
872 return True
837
873
874 @annotatesubrepoerror
838 def files(self):
875 def files(self):
839 output = self._svncommand(['list', '--recursive', '--xml'])[0]
876 output = self._svncommand(['list', '--recursive', '--xml'])[0]
840 doc = xml.dom.minidom.parseString(output)
877 doc = xml.dom.minidom.parseString(output)
841 paths = []
878 paths = []
842 for e in doc.getElementsByTagName('entry'):
879 for e in doc.getElementsByTagName('entry'):
843 kind = str(e.getAttribute('kind'))
880 kind = str(e.getAttribute('kind'))
844 if kind != 'file':
881 if kind != 'file':
845 continue
882 continue
846 name = ''.join(c.data for c
883 name = ''.join(c.data for c
847 in e.getElementsByTagName('name')[0].childNodes
884 in e.getElementsByTagName('name')[0].childNodes
848 if c.nodeType == c.TEXT_NODE)
885 if c.nodeType == c.TEXT_NODE)
849 paths.append(name.encode('utf-8'))
886 paths.append(name.encode('utf-8'))
850 return paths
887 return paths
851
888
852 def filedata(self, name):
889 def filedata(self, name):
853 return self._svncommand(['cat'], name)[0]
890 return self._svncommand(['cat'], name)[0]
854
891
855
892
856 class gitsubrepo(abstractsubrepo):
893 class gitsubrepo(abstractsubrepo):
857 def __init__(self, ctx, path, state):
894 def __init__(self, ctx, path, state):
858 self._state = state
895 self._state = state
859 self._ctx = ctx
896 self._ctx = ctx
860 self._path = path
897 self._path = path
861 self._relpath = os.path.join(reporelpath(ctx._repo), path)
898 self._relpath = os.path.join(reporelpath(ctx._repo), path)
862 self._abspath = ctx._repo.wjoin(path)
899 self._abspath = ctx._repo.wjoin(path)
863 self._subparent = ctx._repo
900 self._subparent = ctx._repo
864 self._ui = ctx._repo.ui
901 self._ui = ctx._repo.ui
865 self._ensuregit()
902 self._ensuregit()
866
903
867 def _ensuregit(self):
904 def _ensuregit(self):
868 try:
905 try:
869 self._gitexecutable = 'git'
906 self._gitexecutable = 'git'
870 out, err = self._gitnodir(['--version'])
907 out, err = self._gitnodir(['--version'])
871 except OSError, e:
908 except OSError, e:
872 if e.errno != 2 or os.name != 'nt':
909 if e.errno != 2 or os.name != 'nt':
873 raise
910 raise
874 self._gitexecutable = 'git.cmd'
911 self._gitexecutable = 'git.cmd'
875 out, err = self._gitnodir(['--version'])
912 out, err = self._gitnodir(['--version'])
876 m = re.search(r'^git version (\d+)\.(\d+)\.(\d+)', out)
913 m = re.search(r'^git version (\d+)\.(\d+)\.(\d+)', out)
877 if not m:
914 if not m:
878 self._ui.warn(_('cannot retrieve git version'))
915 self._ui.warn(_('cannot retrieve git version'))
879 return
916 return
880 version = (int(m.group(1)), m.group(2), m.group(3))
917 version = (int(m.group(1)), m.group(2), m.group(3))
881 # git 1.4.0 can't work at all, but 1.5.X can in at least some cases,
918 # git 1.4.0 can't work at all, but 1.5.X can in at least some cases,
882 # despite the docstring comment. For now, error on 1.4.0, warn on
919 # despite the docstring comment. For now, error on 1.4.0, warn on
883 # 1.5.0 but attempt to continue.
920 # 1.5.0 but attempt to continue.
884 if version < (1, 5, 0):
921 if version < (1, 5, 0):
885 raise util.Abort(_('git subrepo requires at least 1.6.0 or later'))
922 raise util.Abort(_('git subrepo requires at least 1.6.0 or later'))
886 elif version < (1, 6, 0):
923 elif version < (1, 6, 0):
887 self._ui.warn(_('git subrepo requires at least 1.6.0 or later'))
924 self._ui.warn(_('git subrepo requires at least 1.6.0 or later'))
888
925
889 def _gitcommand(self, commands, env=None, stream=False):
926 def _gitcommand(self, commands, env=None, stream=False):
890 return self._gitdir(commands, env=env, stream=stream)[0]
927 return self._gitdir(commands, env=env, stream=stream)[0]
891
928
892 def _gitdir(self, commands, env=None, stream=False):
929 def _gitdir(self, commands, env=None, stream=False):
893 return self._gitnodir(commands, env=env, stream=stream,
930 return self._gitnodir(commands, env=env, stream=stream,
894 cwd=self._abspath)
931 cwd=self._abspath)
895
932
896 def _gitnodir(self, commands, env=None, stream=False, cwd=None):
933 def _gitnodir(self, commands, env=None, stream=False, cwd=None):
897 """Calls the git command
934 """Calls the git command
898
935
899 The methods tries to call the git command. versions prior to 1.6.0
936 The methods tries to call the git command. versions prior to 1.6.0
900 are not supported and very probably fail.
937 are not supported and very probably fail.
901 """
938 """
902 self._ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
939 self._ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
903 # unless ui.quiet is set, print git's stderr,
940 # unless ui.quiet is set, print git's stderr,
904 # which is mostly progress and useful info
941 # which is mostly progress and useful info
905 errpipe = None
942 errpipe = None
906 if self._ui.quiet:
943 if self._ui.quiet:
907 errpipe = open(os.devnull, 'w')
944 errpipe = open(os.devnull, 'w')
908 p = subprocess.Popen([self._gitexecutable] + commands, bufsize=-1,
945 p = subprocess.Popen([self._gitexecutable] + commands, bufsize=-1,
909 cwd=cwd, env=env, close_fds=util.closefds,
946 cwd=cwd, env=env, close_fds=util.closefds,
910 stdout=subprocess.PIPE, stderr=errpipe)
947 stdout=subprocess.PIPE, stderr=errpipe)
911 if stream:
948 if stream:
912 return p.stdout, None
949 return p.stdout, None
913
950
914 retdata = p.stdout.read().strip()
951 retdata = p.stdout.read().strip()
915 # wait for the child to exit to avoid race condition.
952 # wait for the child to exit to avoid race condition.
916 p.wait()
953 p.wait()
917
954
918 if p.returncode != 0 and p.returncode != 1:
955 if p.returncode != 0 and p.returncode != 1:
919 # there are certain error codes that are ok
956 # there are certain error codes that are ok
920 command = commands[0]
957 command = commands[0]
921 if command in ('cat-file', 'symbolic-ref'):
958 if command in ('cat-file', 'symbolic-ref'):
922 return retdata, p.returncode
959 return retdata, p.returncode
923 # for all others, abort
960 # for all others, abort
924 raise util.Abort('git %s error %d in %s' %
961 raise util.Abort('git %s error %d in %s' %
925 (command, p.returncode, self._relpath))
962 (command, p.returncode, self._relpath))
926
963
927 return retdata, p.returncode
964 return retdata, p.returncode
928
965
929 def _gitmissing(self):
966 def _gitmissing(self):
930 return not os.path.exists(os.path.join(self._abspath, '.git'))
967 return not os.path.exists(os.path.join(self._abspath, '.git'))
931
968
932 def _gitstate(self):
969 def _gitstate(self):
933 return self._gitcommand(['rev-parse', 'HEAD'])
970 return self._gitcommand(['rev-parse', 'HEAD'])
934
971
935 def _gitcurrentbranch(self):
972 def _gitcurrentbranch(self):
936 current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet'])
973 current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet'])
937 if err:
974 if err:
938 current = None
975 current = None
939 return current
976 return current
940
977
941 def _gitremote(self, remote):
978 def _gitremote(self, remote):
942 out = self._gitcommand(['remote', 'show', '-n', remote])
979 out = self._gitcommand(['remote', 'show', '-n', remote])
943 line = out.split('\n')[1]
980 line = out.split('\n')[1]
944 i = line.index('URL: ') + len('URL: ')
981 i = line.index('URL: ') + len('URL: ')
945 return line[i:]
982 return line[i:]
946
983
947 def _githavelocally(self, revision):
984 def _githavelocally(self, revision):
948 out, code = self._gitdir(['cat-file', '-e', revision])
985 out, code = self._gitdir(['cat-file', '-e', revision])
949 return code == 0
986 return code == 0
950
987
951 def _gitisancestor(self, r1, r2):
988 def _gitisancestor(self, r1, r2):
952 base = self._gitcommand(['merge-base', r1, r2])
989 base = self._gitcommand(['merge-base', r1, r2])
953 return base == r1
990 return base == r1
954
991
955 def _gitisbare(self):
992 def _gitisbare(self):
956 return self._gitcommand(['config', '--bool', 'core.bare']) == 'true'
993 return self._gitcommand(['config', '--bool', 'core.bare']) == 'true'
957
994
958 def _gitupdatestat(self):
995 def _gitupdatestat(self):
959 """This must be run before git diff-index.
996 """This must be run before git diff-index.
960 diff-index only looks at changes to file stat;
997 diff-index only looks at changes to file stat;
961 this command looks at file contents and updates the stat."""
998 this command looks at file contents and updates the stat."""
962 self._gitcommand(['update-index', '-q', '--refresh'])
999 self._gitcommand(['update-index', '-q', '--refresh'])
963
1000
964 def _gitbranchmap(self):
1001 def _gitbranchmap(self):
965 '''returns 2 things:
1002 '''returns 2 things:
966 a map from git branch to revision
1003 a map from git branch to revision
967 a map from revision to branches'''
1004 a map from revision to branches'''
968 branch2rev = {}
1005 branch2rev = {}
969 rev2branch = {}
1006 rev2branch = {}
970
1007
971 out = self._gitcommand(['for-each-ref', '--format',
1008 out = self._gitcommand(['for-each-ref', '--format',
972 '%(objectname) %(refname)'])
1009 '%(objectname) %(refname)'])
973 for line in out.split('\n'):
1010 for line in out.split('\n'):
974 revision, ref = line.split(' ')
1011 revision, ref = line.split(' ')
975 if (not ref.startswith('refs/heads/') and
1012 if (not ref.startswith('refs/heads/') and
976 not ref.startswith('refs/remotes/')):
1013 not ref.startswith('refs/remotes/')):
977 continue
1014 continue
978 if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'):
1015 if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'):
979 continue # ignore remote/HEAD redirects
1016 continue # ignore remote/HEAD redirects
980 branch2rev[ref] = revision
1017 branch2rev[ref] = revision
981 rev2branch.setdefault(revision, []).append(ref)
1018 rev2branch.setdefault(revision, []).append(ref)
982 return branch2rev, rev2branch
1019 return branch2rev, rev2branch
983
1020
984 def _gittracking(self, branches):
1021 def _gittracking(self, branches):
985 'return map of remote branch to local tracking branch'
1022 'return map of remote branch to local tracking branch'
986 # assumes no more than one local tracking branch for each remote
1023 # assumes no more than one local tracking branch for each remote
987 tracking = {}
1024 tracking = {}
988 for b in branches:
1025 for b in branches:
989 if b.startswith('refs/remotes/'):
1026 if b.startswith('refs/remotes/'):
990 continue
1027 continue
991 bname = b.split('/', 2)[2]
1028 bname = b.split('/', 2)[2]
992 remote = self._gitcommand(['config', 'branch.%s.remote' % bname])
1029 remote = self._gitcommand(['config', 'branch.%s.remote' % bname])
993 if remote:
1030 if remote:
994 ref = self._gitcommand(['config', 'branch.%s.merge' % bname])
1031 ref = self._gitcommand(['config', 'branch.%s.merge' % bname])
995 tracking['refs/remotes/%s/%s' %
1032 tracking['refs/remotes/%s/%s' %
996 (remote, ref.split('/', 2)[2])] = b
1033 (remote, ref.split('/', 2)[2])] = b
997 return tracking
1034 return tracking
998
1035
999 def _abssource(self, source):
1036 def _abssource(self, source):
1000 if '://' not in source:
1037 if '://' not in source:
1001 # recognize the scp syntax as an absolute source
1038 # recognize the scp syntax as an absolute source
1002 colon = source.find(':')
1039 colon = source.find(':')
1003 if colon != -1 and '/' not in source[:colon]:
1040 if colon != -1 and '/' not in source[:colon]:
1004 return source
1041 return source
1005 self._subsource = source
1042 self._subsource = source
1006 return _abssource(self)
1043 return _abssource(self)
1007
1044
1008 def _fetch(self, source, revision):
1045 def _fetch(self, source, revision):
1009 if self._gitmissing():
1046 if self._gitmissing():
1010 source = self._abssource(source)
1047 source = self._abssource(source)
1011 self._ui.status(_('cloning subrepo %s from %s\n') %
1048 self._ui.status(_('cloning subrepo %s from %s\n') %
1012 (self._relpath, source))
1049 (self._relpath, source))
1013 self._gitnodir(['clone', source, self._abspath])
1050 self._gitnodir(['clone', source, self._abspath])
1014 if self._githavelocally(revision):
1051 if self._githavelocally(revision):
1015 return
1052 return
1016 self._ui.status(_('pulling subrepo %s from %s\n') %
1053 self._ui.status(_('pulling subrepo %s from %s\n') %
1017 (self._relpath, self._gitremote('origin')))
1054 (self._relpath, self._gitremote('origin')))
1018 # try only origin: the originally cloned repo
1055 # try only origin: the originally cloned repo
1019 self._gitcommand(['fetch'])
1056 self._gitcommand(['fetch'])
1020 if not self._githavelocally(revision):
1057 if not self._githavelocally(revision):
1021 raise util.Abort(_("revision %s does not exist in subrepo %s\n") %
1058 raise util.Abort(_("revision %s does not exist in subrepo %s\n") %
1022 (revision, self._relpath))
1059 (revision, self._relpath))
1023
1060
1061 @annotatesubrepoerror
1024 def dirty(self, ignoreupdate=False):
1062 def dirty(self, ignoreupdate=False):
1025 if self._gitmissing():
1063 if self._gitmissing():
1026 return self._state[1] != ''
1064 return self._state[1] != ''
1027 if self._gitisbare():
1065 if self._gitisbare():
1028 return True
1066 return True
1029 if not ignoreupdate and self._state[1] != self._gitstate():
1067 if not ignoreupdate and self._state[1] != self._gitstate():
1030 # different version checked out
1068 # different version checked out
1031 return True
1069 return True
1032 # check for staged changes or modified files; ignore untracked files
1070 # check for staged changes or modified files; ignore untracked files
1033 self._gitupdatestat()
1071 self._gitupdatestat()
1034 out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
1072 out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
1035 return code == 1
1073 return code == 1
1036
1074
1037 def basestate(self):
1075 def basestate(self):
1038 return self._gitstate()
1076 return self._gitstate()
1039
1077
1078 @annotatesubrepoerror
1040 def get(self, state, overwrite=False):
1079 def get(self, state, overwrite=False):
1041 source, revision, kind = state
1080 source, revision, kind = state
1042 if not revision:
1081 if not revision:
1043 self.remove()
1082 self.remove()
1044 return
1083 return
1045 self._fetch(source, revision)
1084 self._fetch(source, revision)
1046 # if the repo was set to be bare, unbare it
1085 # if the repo was set to be bare, unbare it
1047 if self._gitisbare():
1086 if self._gitisbare():
1048 self._gitcommand(['config', 'core.bare', 'false'])
1087 self._gitcommand(['config', 'core.bare', 'false'])
1049 if self._gitstate() == revision:
1088 if self._gitstate() == revision:
1050 self._gitcommand(['reset', '--hard', 'HEAD'])
1089 self._gitcommand(['reset', '--hard', 'HEAD'])
1051 return
1090 return
1052 elif self._gitstate() == revision:
1091 elif self._gitstate() == revision:
1053 if overwrite:
1092 if overwrite:
1054 # first reset the index to unmark new files for commit, because
1093 # first reset the index to unmark new files for commit, because
1055 # reset --hard will otherwise throw away files added for commit,
1094 # reset --hard will otherwise throw away files added for commit,
1056 # not just unmark them.
1095 # not just unmark them.
1057 self._gitcommand(['reset', 'HEAD'])
1096 self._gitcommand(['reset', 'HEAD'])
1058 self._gitcommand(['reset', '--hard', 'HEAD'])
1097 self._gitcommand(['reset', '--hard', 'HEAD'])
1059 return
1098 return
1060 branch2rev, rev2branch = self._gitbranchmap()
1099 branch2rev, rev2branch = self._gitbranchmap()
1061
1100
1062 def checkout(args):
1101 def checkout(args):
1063 cmd = ['checkout']
1102 cmd = ['checkout']
1064 if overwrite:
1103 if overwrite:
1065 # first reset the index to unmark new files for commit, because
1104 # first reset the index to unmark new files for commit, because
1066 # the -f option will otherwise throw away files added for
1105 # the -f option will otherwise throw away files added for
1067 # commit, not just unmark them.
1106 # commit, not just unmark them.
1068 self._gitcommand(['reset', 'HEAD'])
1107 self._gitcommand(['reset', 'HEAD'])
1069 cmd.append('-f')
1108 cmd.append('-f')
1070 self._gitcommand(cmd + args)
1109 self._gitcommand(cmd + args)
1071
1110
1072 def rawcheckout():
1111 def rawcheckout():
1073 # no branch to checkout, check it out with no branch
1112 # no branch to checkout, check it out with no branch
1074 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
1113 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
1075 self._relpath)
1114 self._relpath)
1076 self._ui.warn(_('check out a git branch if you intend '
1115 self._ui.warn(_('check out a git branch if you intend '
1077 'to make changes\n'))
1116 'to make changes\n'))
1078 checkout(['-q', revision])
1117 checkout(['-q', revision])
1079
1118
1080 if revision not in rev2branch:
1119 if revision not in rev2branch:
1081 rawcheckout()
1120 rawcheckout()
1082 return
1121 return
1083 branches = rev2branch[revision]
1122 branches = rev2branch[revision]
1084 firstlocalbranch = None
1123 firstlocalbranch = None
1085 for b in branches:
1124 for b in branches:
1086 if b == 'refs/heads/master':
1125 if b == 'refs/heads/master':
1087 # master trumps all other branches
1126 # master trumps all other branches
1088 checkout(['refs/heads/master'])
1127 checkout(['refs/heads/master'])
1089 return
1128 return
1090 if not firstlocalbranch and not b.startswith('refs/remotes/'):
1129 if not firstlocalbranch and not b.startswith('refs/remotes/'):
1091 firstlocalbranch = b
1130 firstlocalbranch = b
1092 if firstlocalbranch:
1131 if firstlocalbranch:
1093 checkout([firstlocalbranch])
1132 checkout([firstlocalbranch])
1094 return
1133 return
1095
1134
1096 tracking = self._gittracking(branch2rev.keys())
1135 tracking = self._gittracking(branch2rev.keys())
1097 # choose a remote branch already tracked if possible
1136 # choose a remote branch already tracked if possible
1098 remote = branches[0]
1137 remote = branches[0]
1099 if remote not in tracking:
1138 if remote not in tracking:
1100 for b in branches:
1139 for b in branches:
1101 if b in tracking:
1140 if b in tracking:
1102 remote = b
1141 remote = b
1103 break
1142 break
1104
1143
1105 if remote not in tracking:
1144 if remote not in tracking:
1106 # create a new local tracking branch
1145 # create a new local tracking branch
1107 local = remote.split('/', 2)[2]
1146 local = remote.split('/', 2)[2]
1108 checkout(['-b', local, remote])
1147 checkout(['-b', local, remote])
1109 elif self._gitisancestor(branch2rev[tracking[remote]], remote):
1148 elif self._gitisancestor(branch2rev[tracking[remote]], remote):
1110 # When updating to a tracked remote branch,
1149 # When updating to a tracked remote branch,
1111 # if the local tracking branch is downstream of it,
1150 # if the local tracking branch is downstream of it,
1112 # a normal `git pull` would have performed a "fast-forward merge"
1151 # a normal `git pull` would have performed a "fast-forward merge"
1113 # which is equivalent to updating the local branch to the remote.
1152 # which is equivalent to updating the local branch to the remote.
1114 # Since we are only looking at branching at update, we need to
1153 # Since we are only looking at branching at update, we need to
1115 # detect this situation and perform this action lazily.
1154 # detect this situation and perform this action lazily.
1116 if tracking[remote] != self._gitcurrentbranch():
1155 if tracking[remote] != self._gitcurrentbranch():
1117 checkout([tracking[remote]])
1156 checkout([tracking[remote]])
1118 self._gitcommand(['merge', '--ff', remote])
1157 self._gitcommand(['merge', '--ff', remote])
1119 else:
1158 else:
1120 # a real merge would be required, just checkout the revision
1159 # a real merge would be required, just checkout the revision
1121 rawcheckout()
1160 rawcheckout()
1122
1161
1162 @annotatesubrepoerror
1123 def commit(self, text, user, date):
1163 def commit(self, text, user, date):
1124 if self._gitmissing():
1164 if self._gitmissing():
1125 raise util.Abort(_("subrepo %s is missing") % self._relpath)
1165 raise util.Abort(_("subrepo %s is missing") % self._relpath)
1126 cmd = ['commit', '-a', '-m', text]
1166 cmd = ['commit', '-a', '-m', text]
1127 env = os.environ.copy()
1167 env = os.environ.copy()
1128 if user:
1168 if user:
1129 cmd += ['--author', user]
1169 cmd += ['--author', user]
1130 if date:
1170 if date:
1131 # git's date parser silently ignores when seconds < 1e9
1171 # git's date parser silently ignores when seconds < 1e9
1132 # convert to ISO8601
1172 # convert to ISO8601
1133 env['GIT_AUTHOR_DATE'] = util.datestr(date,
1173 env['GIT_AUTHOR_DATE'] = util.datestr(date,
1134 '%Y-%m-%dT%H:%M:%S %1%2')
1174 '%Y-%m-%dT%H:%M:%S %1%2')
1135 self._gitcommand(cmd, env=env)
1175 self._gitcommand(cmd, env=env)
1136 # make sure commit works otherwise HEAD might not exist under certain
1176 # make sure commit works otherwise HEAD might not exist under certain
1137 # circumstances
1177 # circumstances
1138 return self._gitstate()
1178 return self._gitstate()
1139
1179
1180 @annotatesubrepoerror
1140 def merge(self, state):
1181 def merge(self, state):
1141 source, revision, kind = state
1182 source, revision, kind = state
1142 self._fetch(source, revision)
1183 self._fetch(source, revision)
1143 base = self._gitcommand(['merge-base', revision, self._state[1]])
1184 base = self._gitcommand(['merge-base', revision, self._state[1]])
1144 self._gitupdatestat()
1185 self._gitupdatestat()
1145 out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
1186 out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
1146
1187
1147 def mergefunc():
1188 def mergefunc():
1148 if base == revision:
1189 if base == revision:
1149 self.get(state) # fast forward merge
1190 self.get(state) # fast forward merge
1150 elif base != self._state[1]:
1191 elif base != self._state[1]:
1151 self._gitcommand(['merge', '--no-commit', revision])
1192 self._gitcommand(['merge', '--no-commit', revision])
1152
1193
1153 if self.dirty():
1194 if self.dirty():
1154 if self._gitstate() != revision:
1195 if self._gitstate() != revision:
1155 dirty = self._gitstate() == self._state[1] or code != 0
1196 dirty = self._gitstate() == self._state[1] or code != 0
1156 if _updateprompt(self._ui, self, dirty,
1197 if _updateprompt(self._ui, self, dirty,
1157 self._state[1][:7], revision[:7]):
1198 self._state[1][:7], revision[:7]):
1158 mergefunc()
1199 mergefunc()
1159 else:
1200 else:
1160 mergefunc()
1201 mergefunc()
1161
1202
1203 @annotatesubrepoerror
1162 def push(self, opts):
1204 def push(self, opts):
1163 force = opts.get('force')
1205 force = opts.get('force')
1164
1206
1165 if not self._state[1]:
1207 if not self._state[1]:
1166 return True
1208 return True
1167 if self._gitmissing():
1209 if self._gitmissing():
1168 raise util.Abort(_("subrepo %s is missing") % self._relpath)
1210 raise util.Abort(_("subrepo %s is missing") % self._relpath)
1169 # if a branch in origin contains the revision, nothing to do
1211 # if a branch in origin contains the revision, nothing to do
1170 branch2rev, rev2branch = self._gitbranchmap()
1212 branch2rev, rev2branch = self._gitbranchmap()
1171 if self._state[1] in rev2branch:
1213 if self._state[1] in rev2branch:
1172 for b in rev2branch[self._state[1]]:
1214 for b in rev2branch[self._state[1]]:
1173 if b.startswith('refs/remotes/origin/'):
1215 if b.startswith('refs/remotes/origin/'):
1174 return True
1216 return True
1175 for b, revision in branch2rev.iteritems():
1217 for b, revision in branch2rev.iteritems():
1176 if b.startswith('refs/remotes/origin/'):
1218 if b.startswith('refs/remotes/origin/'):
1177 if self._gitisancestor(self._state[1], revision):
1219 if self._gitisancestor(self._state[1], revision):
1178 return True
1220 return True
1179 # otherwise, try to push the currently checked out branch
1221 # otherwise, try to push the currently checked out branch
1180 cmd = ['push']
1222 cmd = ['push']
1181 if force:
1223 if force:
1182 cmd.append('--force')
1224 cmd.append('--force')
1183
1225
1184 current = self._gitcurrentbranch()
1226 current = self._gitcurrentbranch()
1185 if current:
1227 if current:
1186 # determine if the current branch is even useful
1228 # determine if the current branch is even useful
1187 if not self._gitisancestor(self._state[1], current):
1229 if not self._gitisancestor(self._state[1], current):
1188 self._ui.warn(_('unrelated git branch checked out '
1230 self._ui.warn(_('unrelated git branch checked out '
1189 'in subrepo %s\n') % self._relpath)
1231 'in subrepo %s\n') % self._relpath)
1190 return False
1232 return False
1191 self._ui.status(_('pushing branch %s of subrepo %s\n') %
1233 self._ui.status(_('pushing branch %s of subrepo %s\n') %
1192 (current.split('/', 2)[2], self._relpath))
1234 (current.split('/', 2)[2], self._relpath))
1193 self._gitcommand(cmd + ['origin', current])
1235 self._gitcommand(cmd + ['origin', current])
1194 return True
1236 return True
1195 else:
1237 else:
1196 self._ui.warn(_('no branch checked out in subrepo %s\n'
1238 self._ui.warn(_('no branch checked out in subrepo %s\n'
1197 'cannot push revision %s\n') %
1239 'cannot push revision %s\n') %
1198 (self._relpath, self._state[1]))
1240 (self._relpath, self._state[1]))
1199 return False
1241 return False
1200
1242
1243 @annotatesubrepoerror
1201 def remove(self):
1244 def remove(self):
1202 if self._gitmissing():
1245 if self._gitmissing():
1203 return
1246 return
1204 if self.dirty():
1247 if self.dirty():
1205 self._ui.warn(_('not removing repo %s because '
1248 self._ui.warn(_('not removing repo %s because '
1206 'it has changes.\n') % self._relpath)
1249 'it has changes.\n') % self._relpath)
1207 return
1250 return
1208 # we can't fully delete the repository as it may contain
1251 # we can't fully delete the repository as it may contain
1209 # local-only history
1252 # local-only history
1210 self._ui.note(_('removing subrepo %s\n') % self._relpath)
1253 self._ui.note(_('removing subrepo %s\n') % self._relpath)
1211 self._gitcommand(['config', 'core.bare', 'true'])
1254 self._gitcommand(['config', 'core.bare', 'true'])
1212 for f in os.listdir(self._abspath):
1255 for f in os.listdir(self._abspath):
1213 if f == '.git':
1256 if f == '.git':
1214 continue
1257 continue
1215 path = os.path.join(self._abspath, f)
1258 path = os.path.join(self._abspath, f)
1216 if os.path.isdir(path) and not os.path.islink(path):
1259 if os.path.isdir(path) and not os.path.islink(path):
1217 shutil.rmtree(path)
1260 shutil.rmtree(path)
1218 else:
1261 else:
1219 os.remove(path)
1262 os.remove(path)
1220
1263
1221 def archive(self, ui, archiver, prefix, match=None):
1264 def archive(self, ui, archiver, prefix, match=None):
1222 source, revision = self._state
1265 source, revision = self._state
1223 if not revision:
1266 if not revision:
1224 return
1267 return
1225 self._fetch(source, revision)
1268 self._fetch(source, revision)
1226
1269
1227 # Parse git's native archive command.
1270 # Parse git's native archive command.
1228 # This should be much faster than manually traversing the trees
1271 # This should be much faster than manually traversing the trees
1229 # and objects with many subprocess calls.
1272 # and objects with many subprocess calls.
1230 tarstream = self._gitcommand(['archive', revision], stream=True)
1273 tarstream = self._gitcommand(['archive', revision], stream=True)
1231 tar = tarfile.open(fileobj=tarstream, mode='r|')
1274 tar = tarfile.open(fileobj=tarstream, mode='r|')
1232 relpath = subrelpath(self)
1275 relpath = subrelpath(self)
1233 ui.progress(_('archiving (%s)') % relpath, 0, unit=_('files'))
1276 ui.progress(_('archiving (%s)') % relpath, 0, unit=_('files'))
1234 for i, info in enumerate(tar):
1277 for i, info in enumerate(tar):
1235 if info.isdir():
1278 if info.isdir():
1236 continue
1279 continue
1237 if match and not match(info.name):
1280 if match and not match(info.name):
1238 continue
1281 continue
1239 if info.issym():
1282 if info.issym():
1240 data = info.linkname
1283 data = info.linkname
1241 else:
1284 else:
1242 data = tar.extractfile(info).read()
1285 data = tar.extractfile(info).read()
1243 archiver.addfile(os.path.join(prefix, self._path, info.name),
1286 archiver.addfile(os.path.join(prefix, self._path, info.name),
1244 info.mode, info.issym(), data)
1287 info.mode, info.issym(), data)
1245 ui.progress(_('archiving (%s)') % relpath, i + 1,
1288 ui.progress(_('archiving (%s)') % relpath, i + 1,
1246 unit=_('files'))
1289 unit=_('files'))
1247 ui.progress(_('archiving (%s)') % relpath, None)
1290 ui.progress(_('archiving (%s)') % relpath, None)
1248
1291
1249
1292
1293 @annotatesubrepoerror
1250 def status(self, rev2, **opts):
1294 def status(self, rev2, **opts):
1251 rev1 = self._state[1]
1295 rev1 = self._state[1]
1252 if self._gitmissing() or not rev1:
1296 if self._gitmissing() or not rev1:
1253 # if the repo is missing, return no results
1297 # if the repo is missing, return no results
1254 return [], [], [], [], [], [], []
1298 return [], [], [], [], [], [], []
1255 modified, added, removed = [], [], []
1299 modified, added, removed = [], [], []
1256 self._gitupdatestat()
1300 self._gitupdatestat()
1257 if rev2:
1301 if rev2:
1258 command = ['diff-tree', rev1, rev2]
1302 command = ['diff-tree', rev1, rev2]
1259 else:
1303 else:
1260 command = ['diff-index', rev1]
1304 command = ['diff-index', rev1]
1261 out = self._gitcommand(command)
1305 out = self._gitcommand(command)
1262 for line in out.split('\n'):
1306 for line in out.split('\n'):
1263 tab = line.find('\t')
1307 tab = line.find('\t')
1264 if tab == -1:
1308 if tab == -1:
1265 continue
1309 continue
1266 status, f = line[tab - 1], line[tab + 1:]
1310 status, f = line[tab - 1], line[tab + 1:]
1267 if status == 'M':
1311 if status == 'M':
1268 modified.append(f)
1312 modified.append(f)
1269 elif status == 'A':
1313 elif status == 'A':
1270 added.append(f)
1314 added.append(f)
1271 elif status == 'D':
1315 elif status == 'D':
1272 removed.append(f)
1316 removed.append(f)
1273
1317
1274 deleted = unknown = ignored = clean = []
1318 deleted = unknown = ignored = clean = []
1275 return modified, added, removed, deleted, unknown, ignored, clean
1319 return modified, added, removed, deleted, unknown, ignored, clean
1276
1320
1277 types = {
1321 types = {
1278 'hg': hgsubrepo,
1322 'hg': hgsubrepo,
1279 'svn': svnsubrepo,
1323 'svn': svnsubrepo,
1280 'git': gitsubrepo,
1324 'git': gitsubrepo,
1281 }
1325 }
@@ -1,534 +1,534 b''
1 $ "$TESTDIR/hghave" git || exit 80
1 $ "$TESTDIR/hghave" git || exit 80
2
2
3 make git commits repeatable
3 make git commits repeatable
4
4
5 $ echo "[core]" >> $HOME/.gitconfig
5 $ echo "[core]" >> $HOME/.gitconfig
6 $ echo "autocrlf = false" >> $HOME/.gitconfig
6 $ echo "autocrlf = false" >> $HOME/.gitconfig
7 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
7 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
8 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
8 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
9 $ GIT_AUTHOR_DATE='1234567891 +0000'; export GIT_AUTHOR_DATE
9 $ GIT_AUTHOR_DATE='1234567891 +0000'; export GIT_AUTHOR_DATE
10 $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
10 $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
11 $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
11 $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
12 $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
12 $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
13
13
14 root hg repo
14 root hg repo
15
15
16 $ hg init t
16 $ hg init t
17 $ cd t
17 $ cd t
18 $ echo a > a
18 $ echo a > a
19 $ hg add a
19 $ hg add a
20 $ hg commit -m a
20 $ hg commit -m a
21 $ cd ..
21 $ cd ..
22
22
23 new external git repo
23 new external git repo
24
24
25 $ mkdir gitroot
25 $ mkdir gitroot
26 $ cd gitroot
26 $ cd gitroot
27 $ git init -q
27 $ git init -q
28 $ echo g > g
28 $ echo g > g
29 $ git add g
29 $ git add g
30 $ git commit -q -m g
30 $ git commit -q -m g
31
31
32 add subrepo clone
32 add subrepo clone
33
33
34 $ cd ../t
34 $ cd ../t
35 $ echo 's = [git]../gitroot' > .hgsub
35 $ echo 's = [git]../gitroot' > .hgsub
36 $ git clone -q ../gitroot s
36 $ git clone -q ../gitroot s
37 $ hg add .hgsub
37 $ hg add .hgsub
38 $ hg commit -m 'new git subrepo'
38 $ hg commit -m 'new git subrepo'
39 $ hg debugsub
39 $ hg debugsub
40 path s
40 path s
41 source ../gitroot
41 source ../gitroot
42 revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
42 revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
43
43
44 record a new commit from upstream from a different branch
44 record a new commit from upstream from a different branch
45
45
46 $ cd ../gitroot
46 $ cd ../gitroot
47 $ git checkout -q -b testing
47 $ git checkout -q -b testing
48 $ echo gg >> g
48 $ echo gg >> g
49 $ git commit -q -a -m gg
49 $ git commit -q -a -m gg
50
50
51 $ cd ../t/s
51 $ cd ../t/s
52 $ git pull -q >/dev/null 2>/dev/null
52 $ git pull -q >/dev/null 2>/dev/null
53 $ git checkout -q -b testing origin/testing >/dev/null
53 $ git checkout -q -b testing origin/testing >/dev/null
54
54
55 $ cd ..
55 $ cd ..
56 $ hg status --subrepos
56 $ hg status --subrepos
57 M s/g
57 M s/g
58 $ hg commit -m 'update git subrepo'
58 $ hg commit -m 'update git subrepo'
59 $ hg debugsub
59 $ hg debugsub
60 path s
60 path s
61 source ../gitroot
61 source ../gitroot
62 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
62 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
63
63
64 make $GITROOT pushable, by replacing it with a clone with nothing checked out
64 make $GITROOT pushable, by replacing it with a clone with nothing checked out
65
65
66 $ cd ..
66 $ cd ..
67 $ git clone gitroot gitrootbare --bare -q
67 $ git clone gitroot gitrootbare --bare -q
68 $ rm -rf gitroot
68 $ rm -rf gitroot
69 $ mv gitrootbare gitroot
69 $ mv gitrootbare gitroot
70
70
71 clone root
71 clone root
72
72
73 $ cd t
73 $ cd t
74 $ hg clone . ../tc
74 $ hg clone . ../tc
75 updating to branch default
75 updating to branch default
76 cloning subrepo s from $TESTTMP/gitroot
76 cloning subrepo s from $TESTTMP/gitroot
77 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ cd ../tc
78 $ cd ../tc
79 $ hg debugsub
79 $ hg debugsub
80 path s
80 path s
81 source ../gitroot
81 source ../gitroot
82 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
82 revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
83
83
84 update to previous substate
84 update to previous substate
85
85
86 $ hg update 1 -q
86 $ hg update 1 -q
87 $ cat s/g
87 $ cat s/g
88 g
88 g
89 $ hg debugsub
89 $ hg debugsub
90 path s
90 path s
91 source ../gitroot
91 source ../gitroot
92 revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
92 revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
93
93
94 clone root, make local change
94 clone root, make local change
95
95
96 $ cd ../t
96 $ cd ../t
97 $ hg clone . ../ta
97 $ hg clone . ../ta
98 updating to branch default
98 updating to branch default
99 cloning subrepo s from $TESTTMP/gitroot
99 cloning subrepo s from $TESTTMP/gitroot
100 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
101
101
102 $ cd ../ta
102 $ cd ../ta
103 $ echo ggg >> s/g
103 $ echo ggg >> s/g
104 $ hg status --subrepos
104 $ hg status --subrepos
105 M s/g
105 M s/g
106 $ hg commit --subrepos -m ggg
106 $ hg commit --subrepos -m ggg
107 committing subrepository s
107 committing subrepository s
108 $ hg debugsub
108 $ hg debugsub
109 path s
109 path s
110 source ../gitroot
110 source ../gitroot
111 revision 79695940086840c99328513acbe35f90fcd55e57
111 revision 79695940086840c99328513acbe35f90fcd55e57
112
112
113 clone root separately, make different local change
113 clone root separately, make different local change
114
114
115 $ cd ../t
115 $ cd ../t
116 $ hg clone . ../tb
116 $ hg clone . ../tb
117 updating to branch default
117 updating to branch default
118 cloning subrepo s from $TESTTMP/gitroot
118 cloning subrepo s from $TESTTMP/gitroot
119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
120
120
121 $ cd ../tb/s
121 $ cd ../tb/s
122 $ echo f > f
122 $ echo f > f
123 $ git add f
123 $ git add f
124 $ cd ..
124 $ cd ..
125
125
126 $ hg status --subrepos
126 $ hg status --subrepos
127 A s/f
127 A s/f
128 $ hg commit --subrepos -m f
128 $ hg commit --subrepos -m f
129 committing subrepository s
129 committing subrepository s
130 $ hg debugsub
130 $ hg debugsub
131 path s
131 path s
132 source ../gitroot
132 source ../gitroot
133 revision aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
133 revision aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
134
134
135 user b push changes
135 user b push changes
136
136
137 $ hg push 2>/dev/null
137 $ hg push 2>/dev/null
138 pushing to $TESTTMP/t (glob)
138 pushing to $TESTTMP/t (glob)
139 pushing branch testing of subrepo s
139 pushing branch testing of subrepo s
140 searching for changes
140 searching for changes
141 adding changesets
141 adding changesets
142 adding manifests
142 adding manifests
143 adding file changes
143 adding file changes
144 added 1 changesets with 1 changes to 1 files
144 added 1 changesets with 1 changes to 1 files
145
145
146 user a pulls, merges, commits
146 user a pulls, merges, commits
147
147
148 $ cd ../ta
148 $ cd ../ta
149 $ hg pull
149 $ hg pull
150 pulling from $TESTTMP/t (glob)
150 pulling from $TESTTMP/t (glob)
151 searching for changes
151 searching for changes
152 adding changesets
152 adding changesets
153 adding manifests
153 adding manifests
154 adding file changes
154 adding file changes
155 added 1 changesets with 1 changes to 1 files (+1 heads)
155 added 1 changesets with 1 changes to 1 files (+1 heads)
156 (run 'hg heads' to see heads, 'hg merge' to merge)
156 (run 'hg heads' to see heads, 'hg merge' to merge)
157 $ hg merge 2>/dev/null
157 $ hg merge 2>/dev/null
158 pulling subrepo s from $TESTTMP/gitroot
158 pulling subrepo s from $TESTTMP/gitroot
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 (branch merge, don't forget to commit)
160 (branch merge, don't forget to commit)
161 $ cat s/f
161 $ cat s/f
162 f
162 f
163 $ cat s/g
163 $ cat s/g
164 g
164 g
165 gg
165 gg
166 ggg
166 ggg
167 $ hg commit --subrepos -m 'merge'
167 $ hg commit --subrepos -m 'merge'
168 committing subrepository s
168 committing subrepository s
169 $ hg status --subrepos --rev 1:5
169 $ hg status --subrepos --rev 1:5
170 M .hgsubstate
170 M .hgsubstate
171 M s/g
171 M s/g
172 A s/f
172 A s/f
173 $ hg debugsub
173 $ hg debugsub
174 path s
174 path s
175 source ../gitroot
175 source ../gitroot
176 revision f47b465e1bce645dbf37232a00574aa1546ca8d3
176 revision f47b465e1bce645dbf37232a00574aa1546ca8d3
177 $ hg push 2>/dev/null
177 $ hg push 2>/dev/null
178 pushing to $TESTTMP/t (glob)
178 pushing to $TESTTMP/t (glob)
179 pushing branch testing of subrepo s
179 pushing branch testing of subrepo s
180 searching for changes
180 searching for changes
181 adding changesets
181 adding changesets
182 adding manifests
182 adding manifests
183 adding file changes
183 adding file changes
184 added 2 changesets with 2 changes to 1 files
184 added 2 changesets with 2 changes to 1 files
185
185
186 make upstream git changes
186 make upstream git changes
187
187
188 $ cd ..
188 $ cd ..
189 $ git clone -q gitroot gitclone
189 $ git clone -q gitroot gitclone
190 $ cd gitclone
190 $ cd gitclone
191 $ echo ff >> f
191 $ echo ff >> f
192 $ git commit -q -a -m ff
192 $ git commit -q -a -m ff
193 $ echo fff >> f
193 $ echo fff >> f
194 $ git commit -q -a -m fff
194 $ git commit -q -a -m fff
195 $ git push origin testing 2>/dev/null
195 $ git push origin testing 2>/dev/null
196
196
197 make and push changes to hg without updating the subrepo
197 make and push changes to hg without updating the subrepo
198
198
199 $ cd ../t
199 $ cd ../t
200 $ hg clone . ../td
200 $ hg clone . ../td
201 updating to branch default
201 updating to branch default
202 cloning subrepo s from $TESTTMP/gitroot
202 cloning subrepo s from $TESTTMP/gitroot
203 checking out detached HEAD in subrepo s
203 checking out detached HEAD in subrepo s
204 check out a git branch if you intend to make changes
204 check out a git branch if you intend to make changes
205 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 $ cd ../td
206 $ cd ../td
207 $ echo aa >> a
207 $ echo aa >> a
208 $ hg commit -m aa
208 $ hg commit -m aa
209 $ hg push
209 $ hg push
210 pushing to $TESTTMP/t (glob)
210 pushing to $TESTTMP/t (glob)
211 searching for changes
211 searching for changes
212 adding changesets
212 adding changesets
213 adding manifests
213 adding manifests
214 adding file changes
214 adding file changes
215 added 1 changesets with 1 changes to 1 files
215 added 1 changesets with 1 changes to 1 files
216
216
217 sync to upstream git, distribute changes
217 sync to upstream git, distribute changes
218
218
219 $ cd ../ta
219 $ cd ../ta
220 $ hg pull -u -q
220 $ hg pull -u -q
221 $ cd s
221 $ cd s
222 $ git pull -q >/dev/null 2>/dev/null
222 $ git pull -q >/dev/null 2>/dev/null
223 $ cd ..
223 $ cd ..
224 $ hg commit -m 'git upstream sync'
224 $ hg commit -m 'git upstream sync'
225 $ hg debugsub
225 $ hg debugsub
226 path s
226 path s
227 source ../gitroot
227 source ../gitroot
228 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
228 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
229 $ hg push -q
229 $ hg push -q
230
230
231 $ cd ../tb
231 $ cd ../tb
232 $ hg pull -q
232 $ hg pull -q
233 $ hg update 2>/dev/null
233 $ hg update 2>/dev/null
234 pulling subrepo s from $TESTTMP/gitroot
234 pulling subrepo s from $TESTTMP/gitroot
235 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
235 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 $ hg debugsub
236 $ hg debugsub
237 path s
237 path s
238 source ../gitroot
238 source ../gitroot
239 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
239 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
240
240
241 update to a revision without the subrepo, keeping the local git repository
241 update to a revision without the subrepo, keeping the local git repository
242
242
243 $ cd ../t
243 $ cd ../t
244 $ hg up 0
244 $ hg up 0
245 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
245 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
246 $ ls -a s
246 $ ls -a s
247 .
247 .
248 ..
248 ..
249 .git
249 .git
250
250
251 $ hg up 2
251 $ hg up 2
252 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
253 $ ls -a s
253 $ ls -a s
254 .
254 .
255 ..
255 ..
256 .git
256 .git
257 g
257 g
258
258
259 archive subrepos
259 archive subrepos
260
260
261 $ cd ../tc
261 $ cd ../tc
262 $ hg pull -q
262 $ hg pull -q
263 $ hg archive --subrepos -r 5 ../archive 2>/dev/null
263 $ hg archive --subrepos -r 5 ../archive 2>/dev/null
264 pulling subrepo s from $TESTTMP/gitroot
264 pulling subrepo s from $TESTTMP/gitroot
265 $ cd ../archive
265 $ cd ../archive
266 $ cat s/f
266 $ cat s/f
267 f
267 f
268 $ cat s/g
268 $ cat s/g
269 g
269 g
270 gg
270 gg
271 ggg
271 ggg
272
272
273 $ hg -R ../tc archive --subrepo -r 5 -X ../tc/**f ../archive_x 2>/dev/null
273 $ hg -R ../tc archive --subrepo -r 5 -X ../tc/**f ../archive_x 2>/dev/null
274 $ find ../archive_x | sort | grep -v pax_global_header
274 $ find ../archive_x | sort | grep -v pax_global_header
275 ../archive_x
275 ../archive_x
276 ../archive_x/.hg_archival.txt
276 ../archive_x/.hg_archival.txt
277 ../archive_x/.hgsub
277 ../archive_x/.hgsub
278 ../archive_x/.hgsubstate
278 ../archive_x/.hgsubstate
279 ../archive_x/a
279 ../archive_x/a
280 ../archive_x/s
280 ../archive_x/s
281 ../archive_x/s/g
281 ../archive_x/s/g
282
282
283 create nested repo
283 create nested repo
284
284
285 $ cd ..
285 $ cd ..
286 $ hg init outer
286 $ hg init outer
287 $ cd outer
287 $ cd outer
288 $ echo b>b
288 $ echo b>b
289 $ hg add b
289 $ hg add b
290 $ hg commit -m b
290 $ hg commit -m b
291
291
292 $ hg clone ../t inner
292 $ hg clone ../t inner
293 updating to branch default
293 updating to branch default
294 cloning subrepo s from $TESTTMP/gitroot
294 cloning subrepo s from $TESTTMP/gitroot
295 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
295 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 $ echo inner = inner > .hgsub
296 $ echo inner = inner > .hgsub
297 $ hg add .hgsub
297 $ hg add .hgsub
298 $ hg commit -m 'nested sub'
298 $ hg commit -m 'nested sub'
299
299
300 nested commit
300 nested commit
301
301
302 $ echo ffff >> inner/s/f
302 $ echo ffff >> inner/s/f
303 $ hg status --subrepos
303 $ hg status --subrepos
304 M inner/s/f
304 M inner/s/f
305 $ hg commit --subrepos -m nested
305 $ hg commit --subrepos -m nested
306 committing subrepository inner
306 committing subrepository inner
307 committing subrepository inner/s (glob)
307 committing subrepository inner/s (glob)
308
308
309 nested archive
309 nested archive
310
310
311 $ hg archive --subrepos ../narchive
311 $ hg archive --subrepos ../narchive
312 $ ls ../narchive/inner/s | grep -v pax_global_header
312 $ ls ../narchive/inner/s | grep -v pax_global_header
313 f
313 f
314 g
314 g
315
315
316 relative source expansion
316 relative source expansion
317
317
318 $ cd ..
318 $ cd ..
319 $ mkdir d
319 $ mkdir d
320 $ hg clone t d/t
320 $ hg clone t d/t
321 updating to branch default
321 updating to branch default
322 cloning subrepo s from $TESTTMP/gitroot
322 cloning subrepo s from $TESTTMP/gitroot
323 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
324
324
325 Don't crash if the subrepo is missing
325 Don't crash if the subrepo is missing
326
326
327 $ hg clone t missing -q
327 $ hg clone t missing -q
328 $ cd missing
328 $ cd missing
329 $ rm -rf s
329 $ rm -rf s
330 $ hg status -S
330 $ hg status -S
331 $ hg sum | grep commit
331 $ hg sum | grep commit
332 commit: 1 subrepos
332 commit: 1 subrepos
333 $ hg push -q
333 $ hg push -q
334 abort: subrepo s is missing
334 abort: subrepo s is missing (in subrepo s)
335 [255]
335 [255]
336 $ hg commit --subrepos -qm missing
336 $ hg commit --subrepos -qm missing
337 abort: subrepo s is missing
337 abort: subrepo s is missing (in subrepo s)
338 [255]
338 [255]
339 $ hg update -C
339 $ hg update -C
340 cloning subrepo s from $TESTTMP/gitroot
340 cloning subrepo s from $TESTTMP/gitroot
341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 $ hg sum | grep commit
342 $ hg sum | grep commit
343 commit: (clean)
343 commit: (clean)
344
344
345 Don't crash if the .hgsubstate entry is missing
345 Don't crash if the .hgsubstate entry is missing
346
346
347 $ hg update 1 -q
347 $ hg update 1 -q
348 $ hg rm .hgsubstate
348 $ hg rm .hgsubstate
349 $ hg commit .hgsubstate -m 'no substate'
349 $ hg commit .hgsubstate -m 'no substate'
350 nothing changed
350 nothing changed
351 [1]
351 [1]
352 $ hg tag -l nosubstate
352 $ hg tag -l nosubstate
353 $ hg manifest
353 $ hg manifest
354 .hgsub
354 .hgsub
355 .hgsubstate
355 .hgsubstate
356 a
356 a
357
357
358 $ hg status -S
358 $ hg status -S
359 R .hgsubstate
359 R .hgsubstate
360 $ hg sum | grep commit
360 $ hg sum | grep commit
361 commit: 1 removed, 1 subrepos (new branch head)
361 commit: 1 removed, 1 subrepos (new branch head)
362
362
363 $ hg commit -m 'restore substate'
363 $ hg commit -m 'restore substate'
364 nothing changed
364 nothing changed
365 [1]
365 [1]
366 $ hg manifest
366 $ hg manifest
367 .hgsub
367 .hgsub
368 .hgsubstate
368 .hgsubstate
369 a
369 a
370 $ hg sum | grep commit
370 $ hg sum | grep commit
371 commit: 1 removed, 1 subrepos (new branch head)
371 commit: 1 removed, 1 subrepos (new branch head)
372
372
373 $ hg update -qC nosubstate
373 $ hg update -qC nosubstate
374 $ ls s
374 $ ls s
375 g
375 g
376
376
377 issue3109: false positives in git diff-index
377 issue3109: false positives in git diff-index
378
378
379 $ hg update -q
379 $ hg update -q
380 $ touch -t 200001010000 s/g
380 $ touch -t 200001010000 s/g
381 $ hg status --subrepos
381 $ hg status --subrepos
382 $ touch -t 200001010000 s/g
382 $ touch -t 200001010000 s/g
383 $ hg sum | grep commit
383 $ hg sum | grep commit
384 commit: (clean)
384 commit: (clean)
385
385
386 Check hg update --clean
386 Check hg update --clean
387 $ cd $TESTTMP/ta
387 $ cd $TESTTMP/ta
388 $ echo > s/g
388 $ echo > s/g
389 $ cd s
389 $ cd s
390 $ echo c1 > f1
390 $ echo c1 > f1
391 $ echo c1 > f2
391 $ echo c1 > f2
392 $ git add f1
392 $ git add f1
393 $ cd ..
393 $ cd ..
394 $ hg status -S
394 $ hg status -S
395 M s/g
395 M s/g
396 A s/f1
396 A s/f1
397 $ ls s
397 $ ls s
398 f
398 f
399 f1
399 f1
400 f2
400 f2
401 g
401 g
402 $ hg update --clean
402 $ hg update --clean
403 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
403 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
404 $ hg status -S
404 $ hg status -S
405 $ ls s
405 $ ls s
406 f
406 f
407 f1
407 f1
408 f2
408 f2
409 g
409 g
410
410
411 Sticky subrepositories, no changes
411 Sticky subrepositories, no changes
412 $ cd $TESTTMP/ta
412 $ cd $TESTTMP/ta
413 $ hg id -n
413 $ hg id -n
414 7
414 7
415 $ cd s
415 $ cd s
416 $ git rev-parse HEAD
416 $ git rev-parse HEAD
417 32a343883b74769118bb1d3b4b1fbf9156f4dddc
417 32a343883b74769118bb1d3b4b1fbf9156f4dddc
418 $ cd ..
418 $ cd ..
419 $ hg update 1 > /dev/null 2>&1
419 $ hg update 1 > /dev/null 2>&1
420 $ hg id -n
420 $ hg id -n
421 1
421 1
422 $ cd s
422 $ cd s
423 $ git rev-parse HEAD
423 $ git rev-parse HEAD
424 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
424 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
425 $ cd ..
425 $ cd ..
426
426
427 Sticky subrepositorys, file changes
427 Sticky subrepositorys, file changes
428 $ touch s/f1
428 $ touch s/f1
429 $ cd s
429 $ cd s
430 $ git add f1
430 $ git add f1
431 $ cd ..
431 $ cd ..
432 $ hg id -n
432 $ hg id -n
433 1+
433 1+
434 $ cd s
434 $ cd s
435 $ git rev-parse HEAD
435 $ git rev-parse HEAD
436 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
436 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
437 $ cd ..
437 $ cd ..
438 $ hg update 4
438 $ hg update 4
439 subrepository sources for s differ
439 subrepository sources for s differ
440 use (l)ocal source (da5f5b1) or (r)emote source (aa84837)?
440 use (l)ocal source (da5f5b1) or (r)emote source (aa84837)?
441 l
441 l
442 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 $ hg id -n
443 $ hg id -n
444 4+
444 4+
445 $ cd s
445 $ cd s
446 $ git rev-parse HEAD
446 $ git rev-parse HEAD
447 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
447 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
448 $ cd ..
448 $ cd ..
449 $ hg update --clean tip > /dev/null 2>&1
449 $ hg update --clean tip > /dev/null 2>&1
450
450
451 Sticky subrepository, revision updates
451 Sticky subrepository, revision updates
452 $ hg id -n
452 $ hg id -n
453 7
453 7
454 $ cd s
454 $ cd s
455 $ git rev-parse HEAD
455 $ git rev-parse HEAD
456 32a343883b74769118bb1d3b4b1fbf9156f4dddc
456 32a343883b74769118bb1d3b4b1fbf9156f4dddc
457 $ cd ..
457 $ cd ..
458 $ cd s
458 $ cd s
459 $ git checkout aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
459 $ git checkout aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
460 Previous HEAD position was 32a3438... fff
460 Previous HEAD position was 32a3438... fff
461 HEAD is now at aa84837... f
461 HEAD is now at aa84837... f
462 $ cd ..
462 $ cd ..
463 $ hg update 1
463 $ hg update 1
464 subrepository sources for s differ (in checked out version)
464 subrepository sources for s differ (in checked out version)
465 use (l)ocal source (32a3438) or (r)emote source (da5f5b1)?
465 use (l)ocal source (32a3438) or (r)emote source (da5f5b1)?
466 l
466 l
467 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
467 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
468 $ hg id -n
468 $ hg id -n
469 1+
469 1+
470 $ cd s
470 $ cd s
471 $ git rev-parse HEAD
471 $ git rev-parse HEAD
472 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
472 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
473 $ cd ..
473 $ cd ..
474
474
475 Sticky subrepository, file changes and revision updates
475 Sticky subrepository, file changes and revision updates
476 $ touch s/f1
476 $ touch s/f1
477 $ cd s
477 $ cd s
478 $ git add f1
478 $ git add f1
479 $ git rev-parse HEAD
479 $ git rev-parse HEAD
480 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
480 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
481 $ cd ..
481 $ cd ..
482 $ hg id -n
482 $ hg id -n
483 1+
483 1+
484 $ hg update 7
484 $ hg update 7
485 subrepository sources for s differ
485 subrepository sources for s differ
486 use (l)ocal source (32a3438) or (r)emote source (32a3438)?
486 use (l)ocal source (32a3438) or (r)emote source (32a3438)?
487 l
487 l
488 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 $ hg id -n
489 $ hg id -n
490 7+
490 7+
491 $ cd s
491 $ cd s
492 $ git rev-parse HEAD
492 $ git rev-parse HEAD
493 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
493 aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
494 $ cd ..
494 $ cd ..
495
495
496 Sticky repository, update --clean
496 Sticky repository, update --clean
497 $ hg update --clean tip 2>/dev/null
497 $ hg update --clean tip 2>/dev/null
498 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 $ hg id -n
499 $ hg id -n
500 7
500 7
501 $ cd s
501 $ cd s
502 $ git rev-parse HEAD
502 $ git rev-parse HEAD
503 32a343883b74769118bb1d3b4b1fbf9156f4dddc
503 32a343883b74769118bb1d3b4b1fbf9156f4dddc
504 $ cd ..
504 $ cd ..
505
505
506 Test subrepo already at intended revision:
506 Test subrepo already at intended revision:
507 $ cd s
507 $ cd s
508 $ git checkout 32a343883b74769118bb1d3b4b1fbf9156f4dddc
508 $ git checkout 32a343883b74769118bb1d3b4b1fbf9156f4dddc
509 HEAD is now at 32a3438... fff
509 HEAD is now at 32a3438... fff
510 $ cd ..
510 $ cd ..
511 $ hg update 1
511 $ hg update 1
512 Previous HEAD position was 32a3438... fff
512 Previous HEAD position was 32a3438... fff
513 HEAD is now at da5f5b1... g
513 HEAD is now at da5f5b1... g
514 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
514 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
515 $ hg id -n
515 $ hg id -n
516 1
516 1
517 $ cd s
517 $ cd s
518 $ git rev-parse HEAD
518 $ git rev-parse HEAD
519 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
519 da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
520 $ cd ..
520 $ cd ..
521
521
522 Test forgetting files, not implemented in git subrepo, used to
522 Test forgetting files, not implemented in git subrepo, used to
523 traceback
523 traceback
524 #if no-windows
524 #if no-windows
525 $ hg forget 'notafile*'
525 $ hg forget 'notafile*'
526 notafile*: No such file or directory
526 notafile*: No such file or directory
527 [1]
527 [1]
528 #else
528 #else
529 $ hg forget 'notafile'
529 $ hg forget 'notafile'
530 notafile: * (glob)
530 notafile: * (glob)
531 [1]
531 [1]
532 #endif
532 #endif
533
533
534 $ cd ..
534 $ cd ..
@@ -1,500 +1,500 b''
1 Create test repository:
1 Create test repository:
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5 $ echo x1 > x.txt
5 $ echo x1 > x.txt
6
6
7 $ hg init foo
7 $ hg init foo
8 $ cd foo
8 $ cd foo
9 $ echo y1 > y.txt
9 $ echo y1 > y.txt
10
10
11 $ hg init bar
11 $ hg init bar
12 $ cd bar
12 $ cd bar
13 $ echo z1 > z.txt
13 $ echo z1 > z.txt
14
14
15 $ cd ..
15 $ cd ..
16 $ echo 'bar = bar' > .hgsub
16 $ echo 'bar = bar' > .hgsub
17
17
18 $ cd ..
18 $ cd ..
19 $ echo 'foo = foo' > .hgsub
19 $ echo 'foo = foo' > .hgsub
20
20
21 Add files --- .hgsub files must go first to trigger subrepos:
21 Add files --- .hgsub files must go first to trigger subrepos:
22
22
23 $ hg add -S .hgsub
23 $ hg add -S .hgsub
24 $ hg add -S foo/.hgsub
24 $ hg add -S foo/.hgsub
25 $ hg add -S foo/bar
25 $ hg add -S foo/bar
26 adding foo/bar/z.txt (glob)
26 adding foo/bar/z.txt (glob)
27 $ hg add -S
27 $ hg add -S
28 adding x.txt
28 adding x.txt
29 adding foo/y.txt (glob)
29 adding foo/y.txt (glob)
30
30
31 Test recursive status without committing anything:
31 Test recursive status without committing anything:
32
32
33 $ hg status -S
33 $ hg status -S
34 A .hgsub
34 A .hgsub
35 A foo/.hgsub
35 A foo/.hgsub
36 A foo/bar/z.txt
36 A foo/bar/z.txt
37 A foo/y.txt
37 A foo/y.txt
38 A x.txt
38 A x.txt
39
39
40 Test recursive diff without committing anything:
40 Test recursive diff without committing anything:
41
41
42 $ hg diff --nodates -S foo
42 $ hg diff --nodates -S foo
43 diff -r 000000000000 foo/.hgsub
43 diff -r 000000000000 foo/.hgsub
44 --- /dev/null
44 --- /dev/null
45 +++ b/foo/.hgsub
45 +++ b/foo/.hgsub
46 @@ -0,0 +1,1 @@
46 @@ -0,0 +1,1 @@
47 +bar = bar
47 +bar = bar
48 diff -r 000000000000 foo/y.txt
48 diff -r 000000000000 foo/y.txt
49 --- /dev/null
49 --- /dev/null
50 +++ b/foo/y.txt
50 +++ b/foo/y.txt
51 @@ -0,0 +1,1 @@
51 @@ -0,0 +1,1 @@
52 +y1
52 +y1
53 diff -r 000000000000 foo/bar/z.txt
53 diff -r 000000000000 foo/bar/z.txt
54 --- /dev/null
54 --- /dev/null
55 +++ b/foo/bar/z.txt
55 +++ b/foo/bar/z.txt
56 @@ -0,0 +1,1 @@
56 @@ -0,0 +1,1 @@
57 +z1
57 +z1
58
58
59 Commits:
59 Commits:
60
60
61 $ hg commit -m fails
61 $ hg commit -m fails
62 abort: uncommitted changes in subrepo foo
62 abort: uncommitted changes in subrepo foo
63 (use --subrepos for recursive commit)
63 (use --subrepos for recursive commit)
64 [255]
64 [255]
65
65
66 The --subrepos flag overwrite the config setting:
66 The --subrepos flag overwrite the config setting:
67
67
68 $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos
68 $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos
69 committing subrepository foo
69 committing subrepository foo
70 committing subrepository foo/bar (glob)
70 committing subrepository foo/bar (glob)
71
71
72 $ cd foo
72 $ cd foo
73 $ echo y2 >> y.txt
73 $ echo y2 >> y.txt
74 $ hg commit -m 0-1-0
74 $ hg commit -m 0-1-0
75
75
76 $ cd bar
76 $ cd bar
77 $ echo z2 >> z.txt
77 $ echo z2 >> z.txt
78 $ hg commit -m 0-1-1
78 $ hg commit -m 0-1-1
79
79
80 $ cd ..
80 $ cd ..
81 $ hg commit -m 0-2-1
81 $ hg commit -m 0-2-1
82
82
83 $ cd ..
83 $ cd ..
84 $ hg commit -m 1-2-1
84 $ hg commit -m 1-2-1
85
85
86 Change working directory:
86 Change working directory:
87
87
88 $ echo y3 >> foo/y.txt
88 $ echo y3 >> foo/y.txt
89 $ echo z3 >> foo/bar/z.txt
89 $ echo z3 >> foo/bar/z.txt
90 $ hg status -S
90 $ hg status -S
91 M foo/bar/z.txt
91 M foo/bar/z.txt
92 M foo/y.txt
92 M foo/y.txt
93 $ hg diff --nodates -S
93 $ hg diff --nodates -S
94 diff -r d254738c5f5e foo/y.txt
94 diff -r d254738c5f5e foo/y.txt
95 --- a/foo/y.txt
95 --- a/foo/y.txt
96 +++ b/foo/y.txt
96 +++ b/foo/y.txt
97 @@ -1,2 +1,3 @@
97 @@ -1,2 +1,3 @@
98 y1
98 y1
99 y2
99 y2
100 +y3
100 +y3
101 diff -r 9647f22de499 foo/bar/z.txt
101 diff -r 9647f22de499 foo/bar/z.txt
102 --- a/foo/bar/z.txt
102 --- a/foo/bar/z.txt
103 +++ b/foo/bar/z.txt
103 +++ b/foo/bar/z.txt
104 @@ -1,2 +1,3 @@
104 @@ -1,2 +1,3 @@
105 z1
105 z1
106 z2
106 z2
107 +z3
107 +z3
108
108
109 Status call crossing repository boundaries:
109 Status call crossing repository boundaries:
110
110
111 $ hg status -S foo/bar/z.txt
111 $ hg status -S foo/bar/z.txt
112 M foo/bar/z.txt
112 M foo/bar/z.txt
113 $ hg status -S -I 'foo/?.txt'
113 $ hg status -S -I 'foo/?.txt'
114 M foo/y.txt
114 M foo/y.txt
115 $ hg status -S -I '**/?.txt'
115 $ hg status -S -I '**/?.txt'
116 M foo/bar/z.txt
116 M foo/bar/z.txt
117 M foo/y.txt
117 M foo/y.txt
118 $ hg diff --nodates -S -I '**/?.txt'
118 $ hg diff --nodates -S -I '**/?.txt'
119 diff -r d254738c5f5e foo/y.txt
119 diff -r d254738c5f5e foo/y.txt
120 --- a/foo/y.txt
120 --- a/foo/y.txt
121 +++ b/foo/y.txt
121 +++ b/foo/y.txt
122 @@ -1,2 +1,3 @@
122 @@ -1,2 +1,3 @@
123 y1
123 y1
124 y2
124 y2
125 +y3
125 +y3
126 diff -r 9647f22de499 foo/bar/z.txt
126 diff -r 9647f22de499 foo/bar/z.txt
127 --- a/foo/bar/z.txt
127 --- a/foo/bar/z.txt
128 +++ b/foo/bar/z.txt
128 +++ b/foo/bar/z.txt
129 @@ -1,2 +1,3 @@
129 @@ -1,2 +1,3 @@
130 z1
130 z1
131 z2
131 z2
132 +z3
132 +z3
133
133
134 Status from within a subdirectory:
134 Status from within a subdirectory:
135
135
136 $ mkdir dir
136 $ mkdir dir
137 $ cd dir
137 $ cd dir
138 $ echo a1 > a.txt
138 $ echo a1 > a.txt
139 $ hg status -S
139 $ hg status -S
140 M foo/bar/z.txt
140 M foo/bar/z.txt
141 M foo/y.txt
141 M foo/y.txt
142 ? dir/a.txt
142 ? dir/a.txt
143 $ hg diff --nodates -S
143 $ hg diff --nodates -S
144 diff -r d254738c5f5e foo/y.txt
144 diff -r d254738c5f5e foo/y.txt
145 --- a/foo/y.txt
145 --- a/foo/y.txt
146 +++ b/foo/y.txt
146 +++ b/foo/y.txt
147 @@ -1,2 +1,3 @@
147 @@ -1,2 +1,3 @@
148 y1
148 y1
149 y2
149 y2
150 +y3
150 +y3
151 diff -r 9647f22de499 foo/bar/z.txt
151 diff -r 9647f22de499 foo/bar/z.txt
152 --- a/foo/bar/z.txt
152 --- a/foo/bar/z.txt
153 +++ b/foo/bar/z.txt
153 +++ b/foo/bar/z.txt
154 @@ -1,2 +1,3 @@
154 @@ -1,2 +1,3 @@
155 z1
155 z1
156 z2
156 z2
157 +z3
157 +z3
158
158
159 Status with relative path:
159 Status with relative path:
160
160
161 $ hg status -S ..
161 $ hg status -S ..
162 M ../foo/bar/z.txt
162 M ../foo/bar/z.txt
163 M ../foo/y.txt
163 M ../foo/y.txt
164 ? a.txt
164 ? a.txt
165 $ hg diff --nodates -S ..
165 $ hg diff --nodates -S ..
166 diff -r d254738c5f5e foo/y.txt
166 diff -r d254738c5f5e foo/y.txt
167 --- a/foo/y.txt
167 --- a/foo/y.txt
168 +++ b/foo/y.txt
168 +++ b/foo/y.txt
169 @@ -1,2 +1,3 @@
169 @@ -1,2 +1,3 @@
170 y1
170 y1
171 y2
171 y2
172 +y3
172 +y3
173 diff -r 9647f22de499 foo/bar/z.txt
173 diff -r 9647f22de499 foo/bar/z.txt
174 --- a/foo/bar/z.txt
174 --- a/foo/bar/z.txt
175 +++ b/foo/bar/z.txt
175 +++ b/foo/bar/z.txt
176 @@ -1,2 +1,3 @@
176 @@ -1,2 +1,3 @@
177 z1
177 z1
178 z2
178 z2
179 +z3
179 +z3
180 $ cd ..
180 $ cd ..
181
181
182 Cleanup and final commit:
182 Cleanup and final commit:
183
183
184 $ rm -r dir
184 $ rm -r dir
185 $ hg commit --subrepos -m 2-3-2
185 $ hg commit --subrepos -m 2-3-2
186 committing subrepository foo
186 committing subrepository foo
187 committing subrepository foo/bar (glob)
187 committing subrepository foo/bar (glob)
188
188
189 Test explicit path commands within subrepos: add/forget
189 Test explicit path commands within subrepos: add/forget
190 $ echo z1 > foo/bar/z2.txt
190 $ echo z1 > foo/bar/z2.txt
191 $ hg status -S
191 $ hg status -S
192 ? foo/bar/z2.txt
192 ? foo/bar/z2.txt
193 $ hg add foo/bar/z2.txt
193 $ hg add foo/bar/z2.txt
194 $ hg status -S
194 $ hg status -S
195 A foo/bar/z2.txt
195 A foo/bar/z2.txt
196 $ hg forget foo/bar/z2.txt
196 $ hg forget foo/bar/z2.txt
197 $ hg status -S
197 $ hg status -S
198 ? foo/bar/z2.txt
198 ? foo/bar/z2.txt
199 $ hg forget foo/bar/z2.txt
199 $ hg forget foo/bar/z2.txt
200 not removing foo/bar/z2.txt: file is already untracked (glob)
200 not removing foo/bar/z2.txt: file is already untracked (glob)
201 [1]
201 [1]
202 $ hg status -S
202 $ hg status -S
203 ? foo/bar/z2.txt
203 ? foo/bar/z2.txt
204 $ rm foo/bar/z2.txt
204 $ rm foo/bar/z2.txt
205
205
206 Log with the relationships between repo and its subrepo:
206 Log with the relationships between repo and its subrepo:
207
207
208 $ hg log --template '{rev}:{node|short} {desc}\n'
208 $ hg log --template '{rev}:{node|short} {desc}\n'
209 2:1326fa26d0c0 2-3-2
209 2:1326fa26d0c0 2-3-2
210 1:4b3c9ff4f66b 1-2-1
210 1:4b3c9ff4f66b 1-2-1
211 0:23376cbba0d8 0-0-0
211 0:23376cbba0d8 0-0-0
212
212
213 $ hg -R foo log --template '{rev}:{node|short} {desc}\n'
213 $ hg -R foo log --template '{rev}:{node|short} {desc}\n'
214 3:65903cebad86 2-3-2
214 3:65903cebad86 2-3-2
215 2:d254738c5f5e 0-2-1
215 2:d254738c5f5e 0-2-1
216 1:8629ce7dcc39 0-1-0
216 1:8629ce7dcc39 0-1-0
217 0:af048e97ade2 0-0-0
217 0:af048e97ade2 0-0-0
218
218
219 $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n'
219 $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n'
220 2:31ecbdafd357 2-3-2
220 2:31ecbdafd357 2-3-2
221 1:9647f22de499 0-1-1
221 1:9647f22de499 0-1-1
222 0:4904098473f9 0-0-0
222 0:4904098473f9 0-0-0
223
223
224 Status between revisions:
224 Status between revisions:
225
225
226 $ hg status -S
226 $ hg status -S
227 $ hg status -S --rev 0:1
227 $ hg status -S --rev 0:1
228 M .hgsubstate
228 M .hgsubstate
229 M foo/.hgsubstate
229 M foo/.hgsubstate
230 M foo/bar/z.txt
230 M foo/bar/z.txt
231 M foo/y.txt
231 M foo/y.txt
232 $ hg diff --nodates -S -I '**/?.txt' --rev 0:1
232 $ hg diff --nodates -S -I '**/?.txt' --rev 0:1
233 diff -r af048e97ade2 -r d254738c5f5e foo/y.txt
233 diff -r af048e97ade2 -r d254738c5f5e foo/y.txt
234 --- a/foo/y.txt
234 --- a/foo/y.txt
235 +++ b/foo/y.txt
235 +++ b/foo/y.txt
236 @@ -1,1 +1,2 @@
236 @@ -1,1 +1,2 @@
237 y1
237 y1
238 +y2
238 +y2
239 diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt
239 diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt
240 --- a/foo/bar/z.txt
240 --- a/foo/bar/z.txt
241 +++ b/foo/bar/z.txt
241 +++ b/foo/bar/z.txt
242 @@ -1,1 +1,2 @@
242 @@ -1,1 +1,2 @@
243 z1
243 z1
244 +z2
244 +z2
245
245
246 Enable progress extension for archive tests:
246 Enable progress extension for archive tests:
247
247
248 $ cp $HGRCPATH $HGRCPATH.no-progress
248 $ cp $HGRCPATH $HGRCPATH.no-progress
249 $ cat >> $HGRCPATH <<EOF
249 $ cat >> $HGRCPATH <<EOF
250 > [extensions]
250 > [extensions]
251 > progress =
251 > progress =
252 > [progress]
252 > [progress]
253 > assume-tty = 1
253 > assume-tty = 1
254 > delay = 0
254 > delay = 0
255 > format = topic bar number
255 > format = topic bar number
256 > refresh = 0
256 > refresh = 0
257 > width = 60
257 > width = 60
258 > EOF
258 > EOF
259
259
260 Test archiving to a directory tree (the doubled lines in the output
260 Test archiving to a directory tree (the doubled lines in the output
261 only show up in the test output, not in real usage):
261 only show up in the test output, not in real usage):
262
262
263 $ hg archive --subrepos ../archive
263 $ hg archive --subrepos ../archive
264 \r (no-eol) (esc)
264 \r (no-eol) (esc)
265 archiving [ ] 0/3\r (no-eol) (esc)
265 archiving [ ] 0/3\r (no-eol) (esc)
266 archiving [ ] 0/3\r (no-eol) (esc)
266 archiving [ ] 0/3\r (no-eol) (esc)
267 archiving [=============> ] 1/3\r (no-eol) (esc)
267 archiving [=============> ] 1/3\r (no-eol) (esc)
268 archiving [=============> ] 1/3\r (no-eol) (esc)
268 archiving [=============> ] 1/3\r (no-eol) (esc)
269 archiving [===========================> ] 2/3\r (no-eol) (esc)
269 archiving [===========================> ] 2/3\r (no-eol) (esc)
270 archiving [===========================> ] 2/3\r (no-eol) (esc)
270 archiving [===========================> ] 2/3\r (no-eol) (esc)
271 archiving [==========================================>] 3/3\r (no-eol) (esc)
271 archiving [==========================================>] 3/3\r (no-eol) (esc)
272 archiving [==========================================>] 3/3\r (no-eol) (esc)
272 archiving [==========================================>] 3/3\r (no-eol) (esc)
273 \r (no-eol) (esc)
273 \r (no-eol) (esc)
274 \r (no-eol) (esc)
274 \r (no-eol) (esc)
275 archiving (foo) [ ] 0/3\r (no-eol) (esc)
275 archiving (foo) [ ] 0/3\r (no-eol) (esc)
276 archiving (foo) [ ] 0/3\r (no-eol) (esc)
276 archiving (foo) [ ] 0/3\r (no-eol) (esc)
277 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
277 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
278 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
278 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
279 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
279 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
280 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
280 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
281 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
281 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
282 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
282 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
283 \r (no-eol) (esc)
283 \r (no-eol) (esc)
284 \r (no-eol) (esc)
284 \r (no-eol) (esc)
285 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
285 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
286 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
286 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
287 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
287 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
288 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
288 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
289 \r (no-eol) (esc)
289 \r (no-eol) (esc)
290 $ find ../archive | sort
290 $ find ../archive | sort
291 ../archive
291 ../archive
292 ../archive/.hg_archival.txt
292 ../archive/.hg_archival.txt
293 ../archive/.hgsub
293 ../archive/.hgsub
294 ../archive/.hgsubstate
294 ../archive/.hgsubstate
295 ../archive/foo
295 ../archive/foo
296 ../archive/foo/.hgsub
296 ../archive/foo/.hgsub
297 ../archive/foo/.hgsubstate
297 ../archive/foo/.hgsubstate
298 ../archive/foo/bar
298 ../archive/foo/bar
299 ../archive/foo/bar/z.txt
299 ../archive/foo/bar/z.txt
300 ../archive/foo/y.txt
300 ../archive/foo/y.txt
301 ../archive/x.txt
301 ../archive/x.txt
302
302
303 Test archiving to zip file (unzip output is unstable):
303 Test archiving to zip file (unzip output is unstable):
304
304
305 $ hg archive --subrepos ../archive.zip
305 $ hg archive --subrepos ../archive.zip
306 \r (no-eol) (esc)
306 \r (no-eol) (esc)
307 archiving [ ] 0/3\r (no-eol) (esc)
307 archiving [ ] 0/3\r (no-eol) (esc)
308 archiving [ ] 0/3\r (no-eol) (esc)
308 archiving [ ] 0/3\r (no-eol) (esc)
309 archiving [=============> ] 1/3\r (no-eol) (esc)
309 archiving [=============> ] 1/3\r (no-eol) (esc)
310 archiving [=============> ] 1/3\r (no-eol) (esc)
310 archiving [=============> ] 1/3\r (no-eol) (esc)
311 archiving [===========================> ] 2/3\r (no-eol) (esc)
311 archiving [===========================> ] 2/3\r (no-eol) (esc)
312 archiving [===========================> ] 2/3\r (no-eol) (esc)
312 archiving [===========================> ] 2/3\r (no-eol) (esc)
313 archiving [==========================================>] 3/3\r (no-eol) (esc)
313 archiving [==========================================>] 3/3\r (no-eol) (esc)
314 archiving [==========================================>] 3/3\r (no-eol) (esc)
314 archiving [==========================================>] 3/3\r (no-eol) (esc)
315 \r (no-eol) (esc)
315 \r (no-eol) (esc)
316 \r (no-eol) (esc)
316 \r (no-eol) (esc)
317 archiving (foo) [ ] 0/3\r (no-eol) (esc)
317 archiving (foo) [ ] 0/3\r (no-eol) (esc)
318 archiving (foo) [ ] 0/3\r (no-eol) (esc)
318 archiving (foo) [ ] 0/3\r (no-eol) (esc)
319 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
319 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
320 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
320 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
321 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
321 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
322 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
322 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
323 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
323 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
324 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
324 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
325 \r (no-eol) (esc)
325 \r (no-eol) (esc)
326 \r (no-eol) (esc)
326 \r (no-eol) (esc)
327 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
327 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
328 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
328 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
329 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
329 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
330 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
330 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
331 \r (no-eol) (esc)
331 \r (no-eol) (esc)
332
332
333 Test archiving a revision that references a subrepo that is not yet
333 Test archiving a revision that references a subrepo that is not yet
334 cloned:
334 cloned:
335
335
336 $ hg clone -U . ../empty
336 $ hg clone -U . ../empty
337 $ cd ../empty
337 $ cd ../empty
338 $ hg archive --subrepos -r tip ../archive.tar.gz
338 $ hg archive --subrepos -r tip ../archive.tar.gz
339 \r (no-eol) (esc)
339 \r (no-eol) (esc)
340 archiving [ ] 0/3\r (no-eol) (esc)
340 archiving [ ] 0/3\r (no-eol) (esc)
341 archiving [ ] 0/3\r (no-eol) (esc)
341 archiving [ ] 0/3\r (no-eol) (esc)
342 archiving [=============> ] 1/3\r (no-eol) (esc)
342 archiving [=============> ] 1/3\r (no-eol) (esc)
343 archiving [=============> ] 1/3\r (no-eol) (esc)
343 archiving [=============> ] 1/3\r (no-eol) (esc)
344 archiving [===========================> ] 2/3\r (no-eol) (esc)
344 archiving [===========================> ] 2/3\r (no-eol) (esc)
345 archiving [===========================> ] 2/3\r (no-eol) (esc)
345 archiving [===========================> ] 2/3\r (no-eol) (esc)
346 archiving [==========================================>] 3/3\r (no-eol) (esc)
346 archiving [==========================================>] 3/3\r (no-eol) (esc)
347 archiving [==========================================>] 3/3\r (no-eol) (esc)
347 archiving [==========================================>] 3/3\r (no-eol) (esc)
348 \r (no-eol) (esc)
348 \r (no-eol) (esc)
349 \r (no-eol) (esc)
349 \r (no-eol) (esc)
350 archiving (foo) [ ] 0/3\r (no-eol) (esc)
350 archiving (foo) [ ] 0/3\r (no-eol) (esc)
351 archiving (foo) [ ] 0/3\r (no-eol) (esc)
351 archiving (foo) [ ] 0/3\r (no-eol) (esc)
352 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
352 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
353 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
353 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
354 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
354 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
355 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
355 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
356 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
356 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
357 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
357 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
358 \r (no-eol) (esc)
358 \r (no-eol) (esc)
359 \r (no-eol) (esc)
359 \r (no-eol) (esc)
360 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
360 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
361 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
361 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
362 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
362 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
363 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
363 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
364 \r (no-eol) (esc)
364 \r (no-eol) (esc)
365 cloning subrepo foo from $TESTTMP/repo/foo
365 cloning subrepo foo from $TESTTMP/repo/foo
366 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
366 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
367
367
368 The newly cloned subrepos contain no working copy:
368 The newly cloned subrepos contain no working copy:
369
369
370 $ hg -R foo summary
370 $ hg -R foo summary
371 parent: -1:000000000000 (no revision checked out)
371 parent: -1:000000000000 (no revision checked out)
372 branch: default
372 branch: default
373 commit: (clean)
373 commit: (clean)
374 update: 4 new changesets (update)
374 update: 4 new changesets (update)
375
375
376 Disable progress extension and cleanup:
376 Disable progress extension and cleanup:
377
377
378 $ mv $HGRCPATH.no-progress $HGRCPATH
378 $ mv $HGRCPATH.no-progress $HGRCPATH
379
379
380 Test archiving when there is a directory in the way for a subrepo
380 Test archiving when there is a directory in the way for a subrepo
381 created by archive:
381 created by archive:
382
382
383 $ hg clone -U . ../almost-empty
383 $ hg clone -U . ../almost-empty
384 $ cd ../almost-empty
384 $ cd ../almost-empty
385 $ mkdir foo
385 $ mkdir foo
386 $ echo f > foo/f
386 $ echo f > foo/f
387 $ hg archive --subrepos -r tip archive
387 $ hg archive --subrepos -r tip archive
388 cloning subrepo foo from $TESTTMP/empty/foo
388 cloning subrepo foo from $TESTTMP/empty/foo
389 abort: destination '$TESTTMP/almost-empty/foo' is not empty (glob)
389 abort: destination '$TESTTMP/almost-empty/foo' is not empty (in subrepo foo) (glob)
390 [255]
390 [255]
391
391
392 Clone and test outgoing:
392 Clone and test outgoing:
393
393
394 $ cd ..
394 $ cd ..
395 $ hg clone repo repo2
395 $ hg clone repo repo2
396 updating to branch default
396 updating to branch default
397 cloning subrepo foo from $TESTTMP/repo/foo
397 cloning subrepo foo from $TESTTMP/repo/foo
398 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
398 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
399 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
400 $ cd repo2
400 $ cd repo2
401 $ hg outgoing -S
401 $ hg outgoing -S
402 comparing with $TESTTMP/repo (glob)
402 comparing with $TESTTMP/repo (glob)
403 searching for changes
403 searching for changes
404 no changes found
404 no changes found
405 comparing with $TESTTMP/repo/foo
405 comparing with $TESTTMP/repo/foo
406 searching for changes
406 searching for changes
407 no changes found
407 no changes found
408 comparing with $TESTTMP/repo/foo/bar
408 comparing with $TESTTMP/repo/foo/bar
409 searching for changes
409 searching for changes
410 no changes found
410 no changes found
411 [1]
411 [1]
412
412
413 Make nested change:
413 Make nested change:
414
414
415 $ echo y4 >> foo/y.txt
415 $ echo y4 >> foo/y.txt
416 $ hg diff --nodates -S
416 $ hg diff --nodates -S
417 diff -r 65903cebad86 foo/y.txt
417 diff -r 65903cebad86 foo/y.txt
418 --- a/foo/y.txt
418 --- a/foo/y.txt
419 +++ b/foo/y.txt
419 +++ b/foo/y.txt
420 @@ -1,3 +1,4 @@
420 @@ -1,3 +1,4 @@
421 y1
421 y1
422 y2
422 y2
423 y3
423 y3
424 +y4
424 +y4
425 $ hg commit --subrepos -m 3-4-2
425 $ hg commit --subrepos -m 3-4-2
426 committing subrepository foo
426 committing subrepository foo
427 $ hg outgoing -S
427 $ hg outgoing -S
428 comparing with $TESTTMP/repo (glob)
428 comparing with $TESTTMP/repo (glob)
429 searching for changes
429 searching for changes
430 changeset: 3:2655b8ecc4ee
430 changeset: 3:2655b8ecc4ee
431 tag: tip
431 tag: tip
432 user: test
432 user: test
433 date: Thu Jan 01 00:00:00 1970 +0000
433 date: Thu Jan 01 00:00:00 1970 +0000
434 summary: 3-4-2
434 summary: 3-4-2
435
435
436 comparing with $TESTTMP/repo/foo
436 comparing with $TESTTMP/repo/foo
437 searching for changes
437 searching for changes
438 changeset: 4:e96193d6cb36
438 changeset: 4:e96193d6cb36
439 tag: tip
439 tag: tip
440 user: test
440 user: test
441 date: Thu Jan 01 00:00:00 1970 +0000
441 date: Thu Jan 01 00:00:00 1970 +0000
442 summary: 3-4-2
442 summary: 3-4-2
443
443
444 comparing with $TESTTMP/repo/foo/bar
444 comparing with $TESTTMP/repo/foo/bar
445 searching for changes
445 searching for changes
446 no changes found
446 no changes found
447
447
448
448
449 Switch to original repo and setup default path:
449 Switch to original repo and setup default path:
450
450
451 $ cd ../repo
451 $ cd ../repo
452 $ echo '[paths]' >> .hg/hgrc
452 $ echo '[paths]' >> .hg/hgrc
453 $ echo 'default = ../repo2' >> .hg/hgrc
453 $ echo 'default = ../repo2' >> .hg/hgrc
454
454
455 Test incoming:
455 Test incoming:
456
456
457 $ hg incoming -S
457 $ hg incoming -S
458 comparing with $TESTTMP/repo2 (glob)
458 comparing with $TESTTMP/repo2 (glob)
459 searching for changes
459 searching for changes
460 changeset: 3:2655b8ecc4ee
460 changeset: 3:2655b8ecc4ee
461 tag: tip
461 tag: tip
462 user: test
462 user: test
463 date: Thu Jan 01 00:00:00 1970 +0000
463 date: Thu Jan 01 00:00:00 1970 +0000
464 summary: 3-4-2
464 summary: 3-4-2
465
465
466 comparing with $TESTTMP/repo2/foo
466 comparing with $TESTTMP/repo2/foo
467 searching for changes
467 searching for changes
468 changeset: 4:e96193d6cb36
468 changeset: 4:e96193d6cb36
469 tag: tip
469 tag: tip
470 user: test
470 user: test
471 date: Thu Jan 01 00:00:00 1970 +0000
471 date: Thu Jan 01 00:00:00 1970 +0000
472 summary: 3-4-2
472 summary: 3-4-2
473
473
474 comparing with $TESTTMP/repo2/foo/bar
474 comparing with $TESTTMP/repo2/foo/bar
475 searching for changes
475 searching for changes
476 no changes found
476 no changes found
477
477
478 $ hg incoming -S --bundle incoming.hg
478 $ hg incoming -S --bundle incoming.hg
479 abort: cannot combine --bundle and --subrepos
479 abort: cannot combine --bundle and --subrepos
480 [255]
480 [255]
481
481
482 Test missing subrepo:
482 Test missing subrepo:
483
483
484 $ rm -r foo
484 $ rm -r foo
485 $ hg status -S
485 $ hg status -S
486 warning: error "unknown revision '65903cebad86f1a84bd4f1134f62fa7dcb7a1c98'" in subrepository "foo"
486 warning: error "unknown revision '65903cebad86f1a84bd4f1134f62fa7dcb7a1c98'" in subrepository "foo"
487
487
488 Issue2619: IndexError: list index out of range on hg add with subrepos
488 Issue2619: IndexError: list index out of range on hg add with subrepos
489 The subrepo must sorts after the explicit filename.
489 The subrepo must sorts after the explicit filename.
490
490
491 $ cd ..
491 $ cd ..
492 $ hg init test
492 $ hg init test
493 $ cd test
493 $ cd test
494 $ hg init x
494 $ hg init x
495 $ echo "x = x" >> .hgsub
495 $ echo "x = x" >> .hgsub
496 $ hg add .hgsub
496 $ hg add .hgsub
497 $ touch a x/a
497 $ touch a x/a
498 $ hg add a x/a
498 $ hg add a x/a
499
499
500 $ cd ..
500 $ cd ..
@@ -1,625 +1,625 b''
1 $ "$TESTDIR/hghave" svn15 || exit 80
1 $ "$TESTDIR/hghave" svn15 || exit 80
2
2
3 $ SVNREPOPATH=`pwd`/svn-repo
3 $ SVNREPOPATH=`pwd`/svn-repo
4 #if windows
4 #if windows
5 $ SVNREPOURL=file:///`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$SVNREPOPATH"`
5 $ SVNREPOURL=file:///`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$SVNREPOPATH"`
6 #else
6 #else
7 $ SVNREPOURL=file://`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$SVNREPOPATH"`
7 $ SVNREPOURL=file://`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$SVNREPOPATH"`
8 #endif
8 #endif
9
9
10 create subversion repo
10 create subversion repo
11
11
12 $ WCROOT="`pwd`/svn-wc"
12 $ WCROOT="`pwd`/svn-wc"
13 $ svnadmin create svn-repo
13 $ svnadmin create svn-repo
14 $ svn co "$SVNREPOURL" svn-wc
14 $ svn co "$SVNREPOURL" svn-wc
15 Checked out revision 0.
15 Checked out revision 0.
16 $ cd svn-wc
16 $ cd svn-wc
17 $ mkdir src
17 $ mkdir src
18 $ echo alpha > src/alpha
18 $ echo alpha > src/alpha
19 $ svn add src
19 $ svn add src
20 A src
20 A src
21 A src/alpha (glob)
21 A src/alpha (glob)
22 $ mkdir externals
22 $ mkdir externals
23 $ echo other > externals/other
23 $ echo other > externals/other
24 $ svn add externals
24 $ svn add externals
25 A externals
25 A externals
26 A externals/other (glob)
26 A externals/other (glob)
27 $ svn ci -m 'Add alpha'
27 $ svn ci -m 'Add alpha'
28 Adding externals
28 Adding externals
29 Adding externals/other (glob)
29 Adding externals/other (glob)
30 Adding src
30 Adding src
31 Adding src/alpha (glob)
31 Adding src/alpha (glob)
32 Transmitting file data ..
32 Transmitting file data ..
33 Committed revision 1.
33 Committed revision 1.
34 $ svn up -q
34 $ svn up -q
35 $ echo "externals -r1 $SVNREPOURL/externals" > extdef
35 $ echo "externals -r1 $SVNREPOURL/externals" > extdef
36 $ svn propset -F extdef svn:externals src
36 $ svn propset -F extdef svn:externals src
37 property 'svn:externals' set on 'src'
37 property 'svn:externals' set on 'src'
38 $ svn ci -m 'Setting externals'
38 $ svn ci -m 'Setting externals'
39 Sending src
39 Sending src
40
40
41 Committed revision 2.
41 Committed revision 2.
42 $ cd ..
42 $ cd ..
43
43
44 create hg repo
44 create hg repo
45
45
46 $ mkdir sub
46 $ mkdir sub
47 $ cd sub
47 $ cd sub
48 $ hg init t
48 $ hg init t
49 $ cd t
49 $ cd t
50
50
51 first revision, no sub
51 first revision, no sub
52
52
53 $ echo a > a
53 $ echo a > a
54 $ hg ci -Am0
54 $ hg ci -Am0
55 adding a
55 adding a
56
56
57 add first svn sub with leading whitespaces
57 add first svn sub with leading whitespaces
58
58
59 $ echo "s = [svn] $SVNREPOURL/src" >> .hgsub
59 $ echo "s = [svn] $SVNREPOURL/src" >> .hgsub
60 $ echo "subdir/s = [svn] $SVNREPOURL/src" >> .hgsub
60 $ echo "subdir/s = [svn] $SVNREPOURL/src" >> .hgsub
61 $ svn co --quiet "$SVNREPOURL"/src s
61 $ svn co --quiet "$SVNREPOURL"/src s
62 $ mkdir subdir
62 $ mkdir subdir
63 $ svn co --quiet "$SVNREPOURL"/src subdir/s
63 $ svn co --quiet "$SVNREPOURL"/src subdir/s
64 $ hg add .hgsub
64 $ hg add .hgsub
65 $ hg ci -m1
65 $ hg ci -m1
66
66
67 make sure we avoid empty commits (issue2445)
67 make sure we avoid empty commits (issue2445)
68
68
69 $ hg sum
69 $ hg sum
70 parent: 1:* tip (glob)
70 parent: 1:* tip (glob)
71 1
71 1
72 branch: default
72 branch: default
73 commit: (clean)
73 commit: (clean)
74 update: (current)
74 update: (current)
75 $ hg ci -moops
75 $ hg ci -moops
76 nothing changed
76 nothing changed
77 [1]
77 [1]
78
78
79 debugsub
79 debugsub
80
80
81 $ hg debugsub
81 $ hg debugsub
82 path s
82 path s
83 source file://*/svn-repo/src (glob)
83 source file://*/svn-repo/src (glob)
84 revision 2
84 revision 2
85 path subdir/s
85 path subdir/s
86 source file://*/svn-repo/src (glob)
86 source file://*/svn-repo/src (glob)
87 revision 2
87 revision 2
88
88
89 change file in svn and hg, commit
89 change file in svn and hg, commit
90
90
91 $ echo a >> a
91 $ echo a >> a
92 $ echo alpha >> s/alpha
92 $ echo alpha >> s/alpha
93 $ hg sum
93 $ hg sum
94 parent: 1:* tip (glob)
94 parent: 1:* tip (glob)
95 1
95 1
96 branch: default
96 branch: default
97 commit: 1 modified, 1 subrepos
97 commit: 1 modified, 1 subrepos
98 update: (current)
98 update: (current)
99 $ hg commit --subrepos -m 'Message!' | grep -v Updating
99 $ hg commit --subrepos -m 'Message!' | grep -v Updating
100 committing subrepository s
100 committing subrepository s
101 Sending*s/alpha (glob)
101 Sending*s/alpha (glob)
102 Transmitting file data .
102 Transmitting file data .
103 Committed revision 3.
103 Committed revision 3.
104
104
105 Fetching external item into '*s/externals'* (glob)
105 Fetching external item into '*s/externals'* (glob)
106 External at revision 1.
106 External at revision 1.
107
107
108 At revision 3.
108 At revision 3.
109 $ hg debugsub
109 $ hg debugsub
110 path s
110 path s
111 source file://*/svn-repo/src (glob)
111 source file://*/svn-repo/src (glob)
112 revision 3
112 revision 3
113 path subdir/s
113 path subdir/s
114 source file://*/svn-repo/src (glob)
114 source file://*/svn-repo/src (glob)
115 revision 2
115 revision 2
116
116
117 missing svn file, commit should fail
117 missing svn file, commit should fail
118
118
119 $ rm s/alpha
119 $ rm s/alpha
120 $ hg commit --subrepos -m 'abort on missing file'
120 $ hg commit --subrepos -m 'abort on missing file'
121 committing subrepository s
121 committing subrepository s
122 abort: cannot commit missing svn entries
122 abort: cannot commit missing svn entries (in subrepo s)
123 [255]
123 [255]
124 $ svn revert s/alpha > /dev/null
124 $ svn revert s/alpha > /dev/null
125
125
126 add an unrelated revision in svn and update the subrepo to without
126 add an unrelated revision in svn and update the subrepo to without
127 bringing any changes.
127 bringing any changes.
128
128
129 $ svn mkdir "$SVNREPOURL/unrelated" -m 'create unrelated'
129 $ svn mkdir "$SVNREPOURL/unrelated" -m 'create unrelated'
130
130
131 Committed revision 4.
131 Committed revision 4.
132 $ svn up -q s
132 $ svn up -q s
133 $ hg sum
133 $ hg sum
134 parent: 2:* tip (glob)
134 parent: 2:* tip (glob)
135 Message!
135 Message!
136 branch: default
136 branch: default
137 commit: (clean)
137 commit: (clean)
138 update: (current)
138 update: (current)
139
139
140 $ echo a > s/a
140 $ echo a > s/a
141
141
142 should be empty despite change to s/a
142 should be empty despite change to s/a
143
143
144 $ hg st
144 $ hg st
145
145
146 add a commit from svn
146 add a commit from svn
147
147
148 $ cd "$WCROOT/src"
148 $ cd "$WCROOT/src"
149 $ svn up -q
149 $ svn up -q
150 $ echo xyz >> alpha
150 $ echo xyz >> alpha
151 $ svn propset svn:mime-type 'text/xml' alpha
151 $ svn propset svn:mime-type 'text/xml' alpha
152 property 'svn:mime-type' set on 'alpha'
152 property 'svn:mime-type' set on 'alpha'
153 $ svn ci -m 'amend a from svn'
153 $ svn ci -m 'amend a from svn'
154 Sending *alpha (glob)
154 Sending *alpha (glob)
155 Transmitting file data .
155 Transmitting file data .
156 Committed revision 5.
156 Committed revision 5.
157 $ cd ../../sub/t
157 $ cd ../../sub/t
158
158
159 this commit from hg will fail
159 this commit from hg will fail
160
160
161 $ echo zzz >> s/alpha
161 $ echo zzz >> s/alpha
162 $ (hg ci --subrepos -m 'amend alpha from hg' 2>&1; echo "[$?]") | grep -vi 'out of date'
162 $ (hg ci --subrepos -m 'amend alpha from hg' 2>&1; echo "[$?]") | grep -vi 'out of date'
163 committing subrepository s
163 committing subrepository s
164 abort: svn:*Commit failed (details follow): (glob)
164 abort: svn:*Commit failed (details follow): (glob)
165 [255]
165 [255]
166 $ svn revert -q s/alpha
166 $ svn revert -q s/alpha
167
167
168 this commit fails because of meta changes
168 this commit fails because of meta changes
169
169
170 $ svn propset svn:mime-type 'text/html' s/alpha
170 $ svn propset svn:mime-type 'text/html' s/alpha
171 property 'svn:mime-type' set on 's/alpha' (glob)
171 property 'svn:mime-type' set on 's/alpha' (glob)
172 $ (hg ci --subrepos -m 'amend alpha from hg' 2>&1; echo "[$?]") | grep -vi 'out of date'
172 $ (hg ci --subrepos -m 'amend alpha from hg' 2>&1; echo "[$?]") | grep -vi 'out of date'
173 committing subrepository s
173 committing subrepository s
174 abort: svn:*Commit failed (details follow): (glob)
174 abort: svn:*Commit failed (details follow): (glob)
175 [255]
175 [255]
176 $ svn revert -q s/alpha
176 $ svn revert -q s/alpha
177
177
178 this commit fails because of externals changes
178 this commit fails because of externals changes
179
179
180 $ echo zzz > s/externals/other
180 $ echo zzz > s/externals/other
181 $ hg ci --subrepos -m 'amend externals from hg'
181 $ hg ci --subrepos -m 'amend externals from hg'
182 committing subrepository s
182 committing subrepository s
183 abort: cannot commit svn externals
183 abort: cannot commit svn externals (in subrepo s)
184 [255]
184 [255]
185 $ hg diff --subrepos -r 1:2 | grep -v diff
185 $ hg diff --subrepos -r 1:2 | grep -v diff
186 --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
186 --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
187 +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
187 +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
188 @@ -1,2 +1,2 @@
188 @@ -1,2 +1,2 @@
189 -2 s
189 -2 s
190 +3 s
190 +3 s
191 2 subdir/s
191 2 subdir/s
192 --- a/a Thu Jan 01 00:00:00 1970 +0000
192 --- a/a Thu Jan 01 00:00:00 1970 +0000
193 +++ b/a Thu Jan 01 00:00:00 1970 +0000
193 +++ b/a Thu Jan 01 00:00:00 1970 +0000
194 @@ -1,1 +1,2 @@
194 @@ -1,1 +1,2 @@
195 a
195 a
196 +a
196 +a
197 $ svn revert -q s/externals/other
197 $ svn revert -q s/externals/other
198
198
199 this commit fails because of externals meta changes
199 this commit fails because of externals meta changes
200
200
201 $ svn propset svn:mime-type 'text/html' s/externals/other
201 $ svn propset svn:mime-type 'text/html' s/externals/other
202 property 'svn:mime-type' set on 's/externals/other' (glob)
202 property 'svn:mime-type' set on 's/externals/other' (glob)
203 $ hg ci --subrepos -m 'amend externals from hg'
203 $ hg ci --subrepos -m 'amend externals from hg'
204 committing subrepository s
204 committing subrepository s
205 abort: cannot commit svn externals
205 abort: cannot commit svn externals (in subrepo s)
206 [255]
206 [255]
207 $ svn revert -q s/externals/other
207 $ svn revert -q s/externals/other
208
208
209 clone
209 clone
210
210
211 $ cd ..
211 $ cd ..
212 $ hg clone t tc
212 $ hg clone t tc
213 updating to branch default
213 updating to branch default
214 A tc/s/alpha (glob)
214 A tc/s/alpha (glob)
215 U tc/s (glob)
215 U tc/s (glob)
216
216
217 Fetching external item into 'tc/s/externals'* (glob)
217 Fetching external item into 'tc/s/externals'* (glob)
218 A tc/s/externals/other (glob)
218 A tc/s/externals/other (glob)
219 Checked out external at revision 1.
219 Checked out external at revision 1.
220
220
221 Checked out revision 3.
221 Checked out revision 3.
222 A tc/subdir/s/alpha (glob)
222 A tc/subdir/s/alpha (glob)
223 U tc/subdir/s (glob)
223 U tc/subdir/s (glob)
224
224
225 Fetching external item into 'tc/subdir/s/externals'* (glob)
225 Fetching external item into 'tc/subdir/s/externals'* (glob)
226 A tc/subdir/s/externals/other (glob)
226 A tc/subdir/s/externals/other (glob)
227 Checked out external at revision 1.
227 Checked out external at revision 1.
228
228
229 Checked out revision 2.
229 Checked out revision 2.
230 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
230 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 $ cd tc
231 $ cd tc
232
232
233 debugsub in clone
233 debugsub in clone
234
234
235 $ hg debugsub
235 $ hg debugsub
236 path s
236 path s
237 source file://*/svn-repo/src (glob)
237 source file://*/svn-repo/src (glob)
238 revision 3
238 revision 3
239 path subdir/s
239 path subdir/s
240 source file://*/svn-repo/src (glob)
240 source file://*/svn-repo/src (glob)
241 revision 2
241 revision 2
242
242
243 verify subrepo is contained within the repo directory
243 verify subrepo is contained within the repo directory
244
244
245 $ python -c "import os.path; print os.path.exists('s')"
245 $ python -c "import os.path; print os.path.exists('s')"
246 True
246 True
247
247
248 update to nullrev (must delete the subrepo)
248 update to nullrev (must delete the subrepo)
249
249
250 $ hg up null
250 $ hg up null
251 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
251 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
252 $ ls
252 $ ls
253
253
254 Check hg update --clean
254 Check hg update --clean
255 $ cd "$TESTTMP/sub/t"
255 $ cd "$TESTTMP/sub/t"
256 $ cd s
256 $ cd s
257 $ echo c0 > alpha
257 $ echo c0 > alpha
258 $ echo c1 > f1
258 $ echo c1 > f1
259 $ echo c1 > f2
259 $ echo c1 > f2
260 $ svn add f1 -q
260 $ svn add f1 -q
261 $ svn status | sort
261 $ svn status | sort
262
262
263 ? * a (glob)
263 ? * a (glob)
264 ? * f2 (glob)
264 ? * f2 (glob)
265 A * f1 (glob)
265 A * f1 (glob)
266 M * alpha (glob)
266 M * alpha (glob)
267 Performing status on external item at 'externals'* (glob)
267 Performing status on external item at 'externals'* (glob)
268 X * externals (glob)
268 X * externals (glob)
269 $ cd ../..
269 $ cd ../..
270 $ hg -R t update -C
270 $ hg -R t update -C
271
271
272 Fetching external item into 't/s/externals'* (glob)
272 Fetching external item into 't/s/externals'* (glob)
273 Checked out external at revision 1.
273 Checked out external at revision 1.
274
274
275 Checked out revision 3.
275 Checked out revision 3.
276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 $ cd t/s
277 $ cd t/s
278 $ svn status | sort
278 $ svn status | sort
279
279
280 ? * a (glob)
280 ? * a (glob)
281 ? * f1 (glob)
281 ? * f1 (glob)
282 ? * f2 (glob)
282 ? * f2 (glob)
283 Performing status on external item at 'externals'* (glob)
283 Performing status on external item at 'externals'* (glob)
284 X * externals (glob)
284 X * externals (glob)
285
285
286 Sticky subrepositories, no changes
286 Sticky subrepositories, no changes
287 $ cd "$TESTTMP/sub/t"
287 $ cd "$TESTTMP/sub/t"
288 $ hg id -n
288 $ hg id -n
289 2
289 2
290 $ cd s
290 $ cd s
291 $ svnversion
291 $ svnversion
292 3
292 3
293 $ cd ..
293 $ cd ..
294 $ hg update 1
294 $ hg update 1
295 U *s/alpha (glob)
295 U *s/alpha (glob)
296
296
297 Fetching external item into '*s/externals'* (glob)
297 Fetching external item into '*s/externals'* (glob)
298 Checked out external at revision 1.
298 Checked out external at revision 1.
299
299
300 Checked out revision 2.
300 Checked out revision 2.
301 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 $ hg id -n
302 $ hg id -n
303 1
303 1
304 $ cd s
304 $ cd s
305 $ svnversion
305 $ svnversion
306 2
306 2
307 $ cd ..
307 $ cd ..
308
308
309 Sticky subrepositorys, file changes
309 Sticky subrepositorys, file changes
310 $ touch s/f1
310 $ touch s/f1
311 $ cd s
311 $ cd s
312 $ svn add f1
312 $ svn add f1
313 A f1
313 A f1
314 $ cd ..
314 $ cd ..
315 $ hg id -n
315 $ hg id -n
316 1+
316 1+
317 $ cd s
317 $ cd s
318 $ svnversion
318 $ svnversion
319 2M
319 2M
320 $ cd ..
320 $ cd ..
321 $ hg update tip
321 $ hg update tip
322 subrepository sources for s differ
322 subrepository sources for s differ
323 use (l)ocal source (2) or (r)emote source (3)?
323 use (l)ocal source (2) or (r)emote source (3)?
324 l
324 l
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 $ hg id -n
326 $ hg id -n
327 2+
327 2+
328 $ cd s
328 $ cd s
329 $ svnversion
329 $ svnversion
330 2M
330 2M
331 $ cd ..
331 $ cd ..
332 $ hg update --clean tip
332 $ hg update --clean tip
333 U *s/alpha (glob)
333 U *s/alpha (glob)
334
334
335 Fetching external item into '*s/externals'* (glob)
335 Fetching external item into '*s/externals'* (glob)
336 Checked out external at revision 1.
336 Checked out external at revision 1.
337
337
338 Checked out revision 3.
338 Checked out revision 3.
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340
340
341 Sticky subrepository, revision updates
341 Sticky subrepository, revision updates
342 $ hg id -n
342 $ hg id -n
343 2
343 2
344 $ cd s
344 $ cd s
345 $ svnversion
345 $ svnversion
346 3
346 3
347 $ cd ..
347 $ cd ..
348 $ cd s
348 $ cd s
349 $ svn update -qr 1
349 $ svn update -qr 1
350 $ cd ..
350 $ cd ..
351 $ hg update 1
351 $ hg update 1
352 subrepository sources for s differ (in checked out version)
352 subrepository sources for s differ (in checked out version)
353 use (l)ocal source (1) or (r)emote source (2)?
353 use (l)ocal source (1) or (r)emote source (2)?
354 l
354 l
355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
356 $ hg id -n
356 $ hg id -n
357 1+
357 1+
358 $ cd s
358 $ cd s
359 $ svnversion
359 $ svnversion
360 1
360 1
361 $ cd ..
361 $ cd ..
362
362
363 Sticky subrepository, file changes and revision updates
363 Sticky subrepository, file changes and revision updates
364 $ touch s/f1
364 $ touch s/f1
365 $ cd s
365 $ cd s
366 $ svn add f1
366 $ svn add f1
367 A f1
367 A f1
368 $ svnversion
368 $ svnversion
369 1M
369 1M
370 $ cd ..
370 $ cd ..
371 $ hg id -n
371 $ hg id -n
372 1+
372 1+
373 $ hg update tip
373 $ hg update tip
374 subrepository sources for s differ
374 subrepository sources for s differ
375 use (l)ocal source (1) or (r)emote source (3)?
375 use (l)ocal source (1) or (r)emote source (3)?
376 l
376 l
377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 $ hg id -n
378 $ hg id -n
379 2+
379 2+
380 $ cd s
380 $ cd s
381 $ svnversion
381 $ svnversion
382 1M
382 1M
383 $ cd ..
383 $ cd ..
384
384
385 Sticky repository, update --clean
385 Sticky repository, update --clean
386 $ hg update --clean tip | grep -v 's[/\]externals[/\]other'
386 $ hg update --clean tip | grep -v 's[/\]externals[/\]other'
387 U *s/alpha (glob)
387 U *s/alpha (glob)
388 U *s (glob)
388 U *s (glob)
389
389
390 Fetching external item into '*s/externals'* (glob)
390 Fetching external item into '*s/externals'* (glob)
391 Checked out external at revision 1.
391 Checked out external at revision 1.
392
392
393 Checked out revision 3.
393 Checked out revision 3.
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 $ hg id -n
395 $ hg id -n
396 2
396 2
397 $ cd s
397 $ cd s
398 $ svnversion
398 $ svnversion
399 3
399 3
400 $ cd ..
400 $ cd ..
401
401
402 Test subrepo already at intended revision:
402 Test subrepo already at intended revision:
403 $ cd s
403 $ cd s
404 $ svn update -qr 2
404 $ svn update -qr 2
405 $ cd ..
405 $ cd ..
406 $ hg update 1
406 $ hg update 1
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 $ hg id -n
408 $ hg id -n
409 1+
409 1+
410 $ cd s
410 $ cd s
411 $ svnversion
411 $ svnversion
412 2
412 2
413 $ cd ..
413 $ cd ..
414
414
415 Test case where subversion would fail to update the subrepo because there
415 Test case where subversion would fail to update the subrepo because there
416 are unknown directories being replaced by tracked ones (happens with rebase).
416 are unknown directories being replaced by tracked ones (happens with rebase).
417
417
418 $ cd "$WCROOT/src"
418 $ cd "$WCROOT/src"
419 $ mkdir dir
419 $ mkdir dir
420 $ echo epsilon.py > dir/epsilon.py
420 $ echo epsilon.py > dir/epsilon.py
421 $ svn add dir
421 $ svn add dir
422 A dir
422 A dir
423 A dir/epsilon.py (glob)
423 A dir/epsilon.py (glob)
424 $ svn ci -m 'Add dir/epsilon.py'
424 $ svn ci -m 'Add dir/epsilon.py'
425 Adding *dir (glob)
425 Adding *dir (glob)
426 Adding *dir/epsilon.py (glob)
426 Adding *dir/epsilon.py (glob)
427 Transmitting file data .
427 Transmitting file data .
428 Committed revision 6.
428 Committed revision 6.
429 $ cd ../..
429 $ cd ../..
430 $ hg init rebaserepo
430 $ hg init rebaserepo
431 $ cd rebaserepo
431 $ cd rebaserepo
432 $ svn co -r5 --quiet "$SVNREPOURL"/src s
432 $ svn co -r5 --quiet "$SVNREPOURL"/src s
433 $ echo "s = [svn] $SVNREPOURL/src" >> .hgsub
433 $ echo "s = [svn] $SVNREPOURL/src" >> .hgsub
434 $ hg add .hgsub
434 $ hg add .hgsub
435 $ hg ci -m addsub
435 $ hg ci -m addsub
436 $ echo a > a
436 $ echo a > a
437 $ hg ci -Am adda
437 $ hg ci -Am adda
438 adding a
438 adding a
439 $ hg up 0
439 $ hg up 0
440 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
440 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
441 $ svn up -qr6 s
441 $ svn up -qr6 s
442 $ hg ci -m updatesub
442 $ hg ci -m updatesub
443 created new head
443 created new head
444 $ echo pyc > s/dir/epsilon.pyc
444 $ echo pyc > s/dir/epsilon.pyc
445 $ hg up 1
445 $ hg up 1
446 D *s/dir (glob)
446 D *s/dir (glob)
447
447
448 Fetching external item into '*s/externals'* (glob)
448 Fetching external item into '*s/externals'* (glob)
449 Checked out external at revision 1.
449 Checked out external at revision 1.
450
450
451 Checked out revision 5.
451 Checked out revision 5.
452 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
452 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
453 $ hg up -q 2
453 $ hg up -q 2
454
454
455 Modify one of the externals to point to a different path so we can
455 Modify one of the externals to point to a different path so we can
456 test having obstructions when switching branches on checkout:
456 test having obstructions when switching branches on checkout:
457 $ hg checkout tip
457 $ hg checkout tip
458 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
458 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 $ echo "obstruct = [svn] $SVNREPOURL/externals" >> .hgsub
459 $ echo "obstruct = [svn] $SVNREPOURL/externals" >> .hgsub
460 $ svn co -r5 --quiet "$SVNREPOURL"/externals obstruct
460 $ svn co -r5 --quiet "$SVNREPOURL"/externals obstruct
461 $ hg commit -m 'Start making obstructed working copy'
461 $ hg commit -m 'Start making obstructed working copy'
462 $ hg book other
462 $ hg book other
463 $ hg co -r 'p1(tip)'
463 $ hg co -r 'p1(tip)'
464 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
464 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
465 $ echo "obstruct = [svn] $SVNREPOURL/src" >> .hgsub
465 $ echo "obstruct = [svn] $SVNREPOURL/src" >> .hgsub
466 $ svn co -r5 --quiet "$SVNREPOURL"/src obstruct
466 $ svn co -r5 --quiet "$SVNREPOURL"/src obstruct
467 $ hg commit -m 'Other branch which will be obstructed'
467 $ hg commit -m 'Other branch which will be obstructed'
468 created new head
468 created new head
469
469
470 Switching back to the head where we have another path mapped to the
470 Switching back to the head where we have another path mapped to the
471 same subrepo should work if the subrepo is clean.
471 same subrepo should work if the subrepo is clean.
472 $ hg co other
472 $ hg co other
473 A *obstruct/other (glob)
473 A *obstruct/other (glob)
474 Checked out revision 1.
474 Checked out revision 1.
475 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
475 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
476
476
477 This is surprising, but is also correct based on the current code:
477 This is surprising, but is also correct based on the current code:
478 $ echo "updating should (maybe) fail" > obstruct/other
478 $ echo "updating should (maybe) fail" > obstruct/other
479 $ hg co tip
479 $ hg co tip
480 abort: crosses branches (merge branches or use --clean to discard changes)
480 abort: crosses branches (merge branches or use --clean to discard changes)
481 [255]
481 [255]
482
482
483 Point to a Subversion branch which has since been deleted and recreated
483 Point to a Subversion branch which has since been deleted and recreated
484 First, create that condition in the repository.
484 First, create that condition in the repository.
485
485
486 $ hg ci --subrepos -m cleanup | grep -v Updating
486 $ hg ci --subrepos -m cleanup | grep -v Updating
487 committing subrepository obstruct
487 committing subrepository obstruct
488 Sending obstruct/other (glob)
488 Sending obstruct/other (glob)
489 Transmitting file data .
489 Transmitting file data .
490 Committed revision 7.
490 Committed revision 7.
491 At revision 7.
491 At revision 7.
492 $ svn mkdir -m "baseline" $SVNREPOURL/trunk
492 $ svn mkdir -m "baseline" $SVNREPOURL/trunk
493
493
494 Committed revision 8.
494 Committed revision 8.
495 $ svn copy -m "initial branch" $SVNREPOURL/trunk $SVNREPOURL/branch
495 $ svn copy -m "initial branch" $SVNREPOURL/trunk $SVNREPOURL/branch
496
496
497 Committed revision 9.
497 Committed revision 9.
498 $ svn co --quiet "$SVNREPOURL"/branch tempwc
498 $ svn co --quiet "$SVNREPOURL"/branch tempwc
499 $ cd tempwc
499 $ cd tempwc
500 $ echo "something old" > somethingold
500 $ echo "something old" > somethingold
501 $ svn add somethingold
501 $ svn add somethingold
502 A somethingold
502 A somethingold
503 $ svn ci -m 'Something old'
503 $ svn ci -m 'Something old'
504 Adding somethingold
504 Adding somethingold
505 Transmitting file data .
505 Transmitting file data .
506 Committed revision 10.
506 Committed revision 10.
507 $ svn rm -m "remove branch" $SVNREPOURL/branch
507 $ svn rm -m "remove branch" $SVNREPOURL/branch
508
508
509 Committed revision 11.
509 Committed revision 11.
510 $ svn copy -m "recreate branch" $SVNREPOURL/trunk $SVNREPOURL/branch
510 $ svn copy -m "recreate branch" $SVNREPOURL/trunk $SVNREPOURL/branch
511
511
512 Committed revision 12.
512 Committed revision 12.
513 $ svn up -q
513 $ svn up -q
514 $ echo "something new" > somethingnew
514 $ echo "something new" > somethingnew
515 $ svn add somethingnew
515 $ svn add somethingnew
516 A somethingnew
516 A somethingnew
517 $ svn ci -m 'Something new'
517 $ svn ci -m 'Something new'
518 Adding somethingnew
518 Adding somethingnew
519 Transmitting file data .
519 Transmitting file data .
520 Committed revision 13.
520 Committed revision 13.
521 $ cd ..
521 $ cd ..
522 $ rm -rf tempwc
522 $ rm -rf tempwc
523 $ svn co "$SVNREPOURL/branch"@10 recreated
523 $ svn co "$SVNREPOURL/branch"@10 recreated
524 A recreated/somethingold (glob)
524 A recreated/somethingold (glob)
525 Checked out revision 10.
525 Checked out revision 10.
526 $ echo "recreated = [svn] $SVNREPOURL/branch" >> .hgsub
526 $ echo "recreated = [svn] $SVNREPOURL/branch" >> .hgsub
527 $ hg ci -m addsub
527 $ hg ci -m addsub
528 $ cd recreated
528 $ cd recreated
529 $ svn up -q
529 $ svn up -q
530 $ cd ..
530 $ cd ..
531 $ hg ci -m updatesub
531 $ hg ci -m updatesub
532 $ hg up -r-2
532 $ hg up -r-2
533 D *recreated/somethingnew (glob)
533 D *recreated/somethingnew (glob)
534 A *recreated/somethingold (glob)
534 A *recreated/somethingold (glob)
535 Checked out revision 10.
535 Checked out revision 10.
536 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
536 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
537 $ test -f recreated/somethingold
537 $ test -f recreated/somethingold
538
538
539 Test archive
539 Test archive
540
540
541 $ hg archive -S ../archive-all --debug
541 $ hg archive -S ../archive-all --debug
542 archiving: 0/2 files (0.00%)
542 archiving: 0/2 files (0.00%)
543 archiving: .hgsub 1/2 files (50.00%)
543 archiving: .hgsub 1/2 files (50.00%)
544 archiving: .hgsubstate 2/2 files (100.00%)
544 archiving: .hgsubstate 2/2 files (100.00%)
545 archiving (obstruct): 0/1 files (0.00%)
545 archiving (obstruct): 0/1 files (0.00%)
546 archiving (obstruct): 1/1 files (100.00%)
546 archiving (obstruct): 1/1 files (100.00%)
547 archiving (s): 0/2 files (0.00%)
547 archiving (s): 0/2 files (0.00%)
548 archiving (s): 1/2 files (50.00%)
548 archiving (s): 1/2 files (50.00%)
549 archiving (s): 2/2 files (100.00%)
549 archiving (s): 2/2 files (100.00%)
550 archiving (recreated): 0/1 files (0.00%)
550 archiving (recreated): 0/1 files (0.00%)
551 archiving (recreated): 1/1 files (100.00%)
551 archiving (recreated): 1/1 files (100.00%)
552
552
553 $ hg archive -S ../archive-exclude --debug -X **old
553 $ hg archive -S ../archive-exclude --debug -X **old
554 archiving: 0/2 files (0.00%)
554 archiving: 0/2 files (0.00%)
555 archiving: .hgsub 1/2 files (50.00%)
555 archiving: .hgsub 1/2 files (50.00%)
556 archiving: .hgsubstate 2/2 files (100.00%)
556 archiving: .hgsubstate 2/2 files (100.00%)
557 archiving (obstruct): 0/1 files (0.00%)
557 archiving (obstruct): 0/1 files (0.00%)
558 archiving (obstruct): 1/1 files (100.00%)
558 archiving (obstruct): 1/1 files (100.00%)
559 archiving (s): 0/2 files (0.00%)
559 archiving (s): 0/2 files (0.00%)
560 archiving (s): 1/2 files (50.00%)
560 archiving (s): 1/2 files (50.00%)
561 archiving (s): 2/2 files (100.00%)
561 archiving (s): 2/2 files (100.00%)
562 archiving (recreated): 0 files
562 archiving (recreated): 0 files
563 $ find ../archive-exclude | sort
563 $ find ../archive-exclude | sort
564 ../archive-exclude
564 ../archive-exclude
565 ../archive-exclude/.hg_archival.txt
565 ../archive-exclude/.hg_archival.txt
566 ../archive-exclude/.hgsub
566 ../archive-exclude/.hgsub
567 ../archive-exclude/.hgsubstate
567 ../archive-exclude/.hgsubstate
568 ../archive-exclude/obstruct
568 ../archive-exclude/obstruct
569 ../archive-exclude/obstruct/other
569 ../archive-exclude/obstruct/other
570 ../archive-exclude/s
570 ../archive-exclude/s
571 ../archive-exclude/s/alpha
571 ../archive-exclude/s/alpha
572 ../archive-exclude/s/dir
572 ../archive-exclude/s/dir
573 ../archive-exclude/s/dir/epsilon.py
573 ../archive-exclude/s/dir/epsilon.py
574
574
575 Test forgetting files, not implemented in svn subrepo, used to
575 Test forgetting files, not implemented in svn subrepo, used to
576 traceback
576 traceback
577
577
578 #if no-windows
578 #if no-windows
579 $ hg forget 'notafile*'
579 $ hg forget 'notafile*'
580 notafile*: No such file or directory
580 notafile*: No such file or directory
581 [1]
581 [1]
582 #else
582 #else
583 $ hg forget 'notafile'
583 $ hg forget 'notafile'
584 notafile: * (glob)
584 notafile: * (glob)
585 [1]
585 [1]
586 #endif
586 #endif
587
587
588 Test a subrepo referencing a just moved svn path. Last commit rev will
588 Test a subrepo referencing a just moved svn path. Last commit rev will
589 be different from the revision, and the path will be different as
589 be different from the revision, and the path will be different as
590 well.
590 well.
591
591
592 $ cd "$WCROOT"
592 $ cd "$WCROOT"
593 $ svn up > /dev/null
593 $ svn up > /dev/null
594 $ mkdir trunk/subdir branches
594 $ mkdir trunk/subdir branches
595 $ echo a > trunk/subdir/a
595 $ echo a > trunk/subdir/a
596 $ svn add trunk/subdir branches
596 $ svn add trunk/subdir branches
597 A trunk/subdir (glob)
597 A trunk/subdir (glob)
598 A trunk/subdir/a (glob)
598 A trunk/subdir/a (glob)
599 A branches
599 A branches
600 $ svn ci -m addsubdir
600 $ svn ci -m addsubdir
601 Adding branches
601 Adding branches
602 Adding trunk/subdir (glob)
602 Adding trunk/subdir (glob)
603 Adding trunk/subdir/a (glob)
603 Adding trunk/subdir/a (glob)
604 Transmitting file data .
604 Transmitting file data .
605 Committed revision 14.
605 Committed revision 14.
606 $ svn cp -m branchtrunk $SVNREPOURL/trunk $SVNREPOURL/branches/somebranch
606 $ svn cp -m branchtrunk $SVNREPOURL/trunk $SVNREPOURL/branches/somebranch
607
607
608 Committed revision 15.
608 Committed revision 15.
609 $ cd ..
609 $ cd ..
610
610
611 $ hg init repo2
611 $ hg init repo2
612 $ cd repo2
612 $ cd repo2
613 $ svn co $SVNREPOURL/branches/somebranch/subdir
613 $ svn co $SVNREPOURL/branches/somebranch/subdir
614 A subdir/a (glob)
614 A subdir/a (glob)
615 Checked out revision 15.
615 Checked out revision 15.
616 $ echo "subdir = [svn] $SVNREPOURL/branches/somebranch/subdir" > .hgsub
616 $ echo "subdir = [svn] $SVNREPOURL/branches/somebranch/subdir" > .hgsub
617 $ hg add .hgsub
617 $ hg add .hgsub
618 $ hg ci -m addsub
618 $ hg ci -m addsub
619 $ hg up null
619 $ hg up null
620 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
620 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
621 $ hg up
621 $ hg up
622 A *subdir/a (glob)
622 A *subdir/a (glob)
623 Checked out revision 15.
623 Checked out revision 15.
624 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
624 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
625 $ cd ..
625 $ cd ..
@@ -1,1053 +1,1053 b''
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5
5
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 first revision, no sub
9 first revision, no sub
10
10
11 $ echo a > a
11 $ echo a > a
12 $ hg ci -Am0
12 $ hg ci -Am0
13 adding a
13 adding a
14
14
15 add first sub
15 add first sub
16
16
17 $ echo s = s > .hgsub
17 $ echo s = s > .hgsub
18 $ hg add .hgsub
18 $ hg add .hgsub
19 $ hg init s
19 $ hg init s
20 $ echo a > s/a
20 $ echo a > s/a
21
21
22 Issue2232: committing a subrepo without .hgsub
22 Issue2232: committing a subrepo without .hgsub
23
23
24 $ hg ci -mbad s
24 $ hg ci -mbad s
25 abort: can't commit subrepos without .hgsub
25 abort: can't commit subrepos without .hgsub
26 [255]
26 [255]
27
27
28 $ hg -R s ci -Ams0
28 $ hg -R s ci -Ams0
29 adding a
29 adding a
30 $ hg sum
30 $ hg sum
31 parent: 0:f7b1eb17ad24 tip
31 parent: 0:f7b1eb17ad24 tip
32 0
32 0
33 branch: default
33 branch: default
34 commit: 1 added, 1 subrepos
34 commit: 1 added, 1 subrepos
35 update: (current)
35 update: (current)
36 $ hg ci -m1
36 $ hg ci -m1
37
37
38 Revert subrepo and test subrepo fileset keyword:
38 Revert subrepo and test subrepo fileset keyword:
39
39
40 $ echo b > s/a
40 $ echo b > s/a
41 $ hg revert "set:subrepo('glob:s*')"
41 $ hg revert "set:subrepo('glob:s*')"
42 reverting subrepo s
42 reverting subrepo s
43 reverting s/a (glob)
43 reverting s/a (glob)
44 $ rm s/a.orig
44 $ rm s/a.orig
45
45
46 Revert subrepo with no backup. The "reverting s/a" line is gone since
46 Revert subrepo with no backup. The "reverting s/a" line is gone since
47 we're really running 'hg update' in the subrepo:
47 we're really running 'hg update' in the subrepo:
48
48
49 $ echo b > s/a
49 $ echo b > s/a
50 $ hg revert --no-backup s
50 $ hg revert --no-backup s
51 reverting subrepo s
51 reverting subrepo s
52
52
53 Issue2022: update -C
53 Issue2022: update -C
54
54
55 $ echo b > s/a
55 $ echo b > s/a
56 $ hg sum
56 $ hg sum
57 parent: 1:7cf8cfea66e4 tip
57 parent: 1:7cf8cfea66e4 tip
58 1
58 1
59 branch: default
59 branch: default
60 commit: 1 subrepos
60 commit: 1 subrepos
61 update: (current)
61 update: (current)
62 $ hg co -C 1
62 $ hg co -C 1
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 $ hg sum
64 $ hg sum
65 parent: 1:7cf8cfea66e4 tip
65 parent: 1:7cf8cfea66e4 tip
66 1
66 1
67 branch: default
67 branch: default
68 commit: (clean)
68 commit: (clean)
69 update: (current)
69 update: (current)
70
70
71 commands that require a clean repo should respect subrepos
71 commands that require a clean repo should respect subrepos
72
72
73 $ echo b >> s/a
73 $ echo b >> s/a
74 $ hg backout tip
74 $ hg backout tip
75 abort: uncommitted changes in subrepo s
75 abort: uncommitted changes in subrepo s
76 [255]
76 [255]
77 $ hg revert -C -R s s/a
77 $ hg revert -C -R s s/a
78
78
79 add sub sub
79 add sub sub
80
80
81 $ echo ss = ss > s/.hgsub
81 $ echo ss = ss > s/.hgsub
82 $ hg init s/ss
82 $ hg init s/ss
83 $ echo a > s/ss/a
83 $ echo a > s/ss/a
84 $ hg -R s add s/.hgsub
84 $ hg -R s add s/.hgsub
85 $ hg -R s/ss add s/ss/a
85 $ hg -R s/ss add s/ss/a
86 $ hg sum
86 $ hg sum
87 parent: 1:7cf8cfea66e4 tip
87 parent: 1:7cf8cfea66e4 tip
88 1
88 1
89 branch: default
89 branch: default
90 commit: 1 subrepos
90 commit: 1 subrepos
91 update: (current)
91 update: (current)
92 $ hg ci -m2
92 $ hg ci -m2
93 committing subrepository s
93 committing subrepository s
94 committing subrepository s/ss (glob)
94 committing subrepository s/ss (glob)
95 $ hg sum
95 $ hg sum
96 parent: 2:df30734270ae tip
96 parent: 2:df30734270ae tip
97 2
97 2
98 branch: default
98 branch: default
99 commit: (clean)
99 commit: (clean)
100 update: (current)
100 update: (current)
101
101
102 bump sub rev (and check it is ignored by ui.commitsubrepos)
102 bump sub rev (and check it is ignored by ui.commitsubrepos)
103
103
104 $ echo b > s/a
104 $ echo b > s/a
105 $ hg -R s ci -ms1
105 $ hg -R s ci -ms1
106 $ hg --config ui.commitsubrepos=no ci -m3
106 $ hg --config ui.commitsubrepos=no ci -m3
107
107
108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
109
109
110 $ echo c > s/a
110 $ echo c > s/a
111 $ hg --config ui.commitsubrepos=no ci -m4
111 $ hg --config ui.commitsubrepos=no ci -m4
112 abort: uncommitted changes in subrepo s
112 abort: uncommitted changes in subrepo s
113 (use --subrepos for recursive commit)
113 (use --subrepos for recursive commit)
114 [255]
114 [255]
115 $ hg id
115 $ hg id
116 f6affe3fbfaa+ tip
116 f6affe3fbfaa+ tip
117 $ hg -R s ci -mc
117 $ hg -R s ci -mc
118 $ hg id
118 $ hg id
119 f6affe3fbfaa+ tip
119 f6affe3fbfaa+ tip
120 $ echo d > s/a
120 $ echo d > s/a
121 $ hg ci -m4
121 $ hg ci -m4
122 committing subrepository s
122 committing subrepository s
123 $ hg tip -R s
123 $ hg tip -R s
124 changeset: 4:02dcf1d70411
124 changeset: 4:02dcf1d70411
125 tag: tip
125 tag: tip
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: 4
128 summary: 4
129
129
130
130
131 check caching
131 check caching
132
132
133 $ hg co 0
133 $ hg co 0
134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
135 $ hg debugsub
135 $ hg debugsub
136
136
137 restore
137 restore
138
138
139 $ hg co
139 $ hg co
140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg debugsub
141 $ hg debugsub
142 path s
142 path s
143 source s
143 source s
144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
145
145
146 new branch for merge tests
146 new branch for merge tests
147
147
148 $ hg co 1
148 $ hg co 1
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 $ echo t = t >> .hgsub
150 $ echo t = t >> .hgsub
151 $ hg init t
151 $ hg init t
152 $ echo t > t/t
152 $ echo t > t/t
153 $ hg -R t add t
153 $ hg -R t add t
154 adding t/t (glob)
154 adding t/t (glob)
155
155
156 5
156 5
157
157
158 $ hg ci -m5 # add sub
158 $ hg ci -m5 # add sub
159 committing subrepository t
159 committing subrepository t
160 created new head
160 created new head
161 $ echo t2 > t/t
161 $ echo t2 > t/t
162
162
163 6
163 6
164
164
165 $ hg st -R s
165 $ hg st -R s
166 $ hg ci -m6 # change sub
166 $ hg ci -m6 # change sub
167 committing subrepository t
167 committing subrepository t
168 $ hg debugsub
168 $ hg debugsub
169 path s
169 path s
170 source s
170 source s
171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
172 path t
172 path t
173 source t
173 source t
174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
175 $ echo t3 > t/t
175 $ echo t3 > t/t
176
176
177 7
177 7
178
178
179 $ hg ci -m7 # change sub again for conflict test
179 $ hg ci -m7 # change sub again for conflict test
180 committing subrepository t
180 committing subrepository t
181 $ hg rm .hgsub
181 $ hg rm .hgsub
182
182
183 8
183 8
184
184
185 $ hg ci -m8 # remove sub
185 $ hg ci -m8 # remove sub
186
186
187 merge tests
187 merge tests
188
188
189 $ hg co -C 3
189 $ hg co -C 3
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 $ hg merge 5 # test adding
191 $ hg merge 5 # test adding
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 (branch merge, don't forget to commit)
193 (branch merge, don't forget to commit)
194 $ hg debugsub
194 $ hg debugsub
195 path s
195 path s
196 source s
196 source s
197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
198 path t
198 path t
199 source t
199 source t
200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
201 $ hg ci -m9
201 $ hg ci -m9
202 created new head
202 created new head
203 $ hg merge 6 --debug # test change
203 $ hg merge 6 --debug # test change
204 searching for copies back to rev 2
204 searching for copies back to rev 2
205 resolving manifests
205 resolving manifests
206 overwrite: False, partial: False
206 overwrite: False, partial: False
207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
208 .hgsubstate: versions differ -> m
208 .hgsubstate: versions differ -> m
209 updating: .hgsubstate 1/1 files (100.00%)
209 updating: .hgsubstate 1/1 files (100.00%)
210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
212 getting subrepo t
212 getting subrepo t
213 searching for copies back to rev 1
213 searching for copies back to rev 1
214 resolving manifests
214 resolving manifests
215 overwrite: False, partial: False
215 overwrite: False, partial: False
216 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
216 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
217 t: remote is newer -> g
217 t: remote is newer -> g
218 updating: t 1/1 files (100.00%)
218 updating: t 1/1 files (100.00%)
219 getting t
219 getting t
220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 (branch merge, don't forget to commit)
221 (branch merge, don't forget to commit)
222 $ hg debugsub
222 $ hg debugsub
223 path s
223 path s
224 source s
224 source s
225 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
225 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
226 path t
226 path t
227 source t
227 source t
228 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
228 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
229 $ echo conflict > t/t
229 $ echo conflict > t/t
230 $ hg ci -m10
230 $ hg ci -m10
231 committing subrepository t
231 committing subrepository t
232 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
232 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
233 searching for copies back to rev 2
233 searching for copies back to rev 2
234 resolving manifests
234 resolving manifests
235 overwrite: False, partial: False
235 overwrite: False, partial: False
236 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
236 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
237 .hgsubstate: versions differ -> m
237 .hgsubstate: versions differ -> m
238 updating: .hgsubstate 1/1 files (100.00%)
238 updating: .hgsubstate 1/1 files (100.00%)
239 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
239 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
240 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
240 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
241 merging subrepo t
241 merging subrepo t
242 searching for copies back to rev 2
242 searching for copies back to rev 2
243 resolving manifests
243 resolving manifests
244 overwrite: False, partial: False
244 overwrite: False, partial: False
245 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
245 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
246 t: versions differ -> m
246 t: versions differ -> m
247 preserving t for resolve of t
247 preserving t for resolve of t
248 updating: t 1/1 files (100.00%)
248 updating: t 1/1 files (100.00%)
249 picked tool 'internal:merge' for t (binary False symlink False)
249 picked tool 'internal:merge' for t (binary False symlink False)
250 merging t
250 merging t
251 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
251 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
252 warning: conflicts during merge.
252 warning: conflicts during merge.
253 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
253 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
254 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
254 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
255 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
255 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 (branch merge, don't forget to commit)
257 (branch merge, don't forget to commit)
258
258
259 should conflict
259 should conflict
260
260
261 $ cat t/t
261 $ cat t/t
262 <<<<<<< local
262 <<<<<<< local
263 conflict
263 conflict
264 =======
264 =======
265 t3
265 t3
266 >>>>>>> other
266 >>>>>>> other
267
267
268 clone
268 clone
269
269
270 $ cd ..
270 $ cd ..
271 $ hg clone t tc
271 $ hg clone t tc
272 updating to branch default
272 updating to branch default
273 cloning subrepo s from $TESTTMP/t/s (glob)
273 cloning subrepo s from $TESTTMP/t/s (glob)
274 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
274 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
275 cloning subrepo t from $TESTTMP/t/t (glob)
275 cloning subrepo t from $TESTTMP/t/t (glob)
276 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 $ cd tc
277 $ cd tc
278 $ hg debugsub
278 $ hg debugsub
279 path s
279 path s
280 source s
280 source s
281 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
281 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
282 path t
282 path t
283 source t
283 source t
284 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
284 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
285
285
286 push
286 push
287
287
288 $ echo bah > t/t
288 $ echo bah > t/t
289 $ hg ci -m11
289 $ hg ci -m11
290 committing subrepository t
290 committing subrepository t
291 $ hg push
291 $ hg push
292 pushing to $TESTTMP/t (glob)
292 pushing to $TESTTMP/t (glob)
293 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
293 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
294 searching for changes
294 searching for changes
295 no changes found
295 no changes found
296 pushing subrepo s to $TESTTMP/t/s (glob)
296 pushing subrepo s to $TESTTMP/t/s (glob)
297 searching for changes
297 searching for changes
298 no changes found
298 no changes found
299 pushing subrepo t to $TESTTMP/t/t (glob)
299 pushing subrepo t to $TESTTMP/t/t (glob)
300 searching for changes
300 searching for changes
301 adding changesets
301 adding changesets
302 adding manifests
302 adding manifests
303 adding file changes
303 adding file changes
304 added 1 changesets with 1 changes to 1 files
304 added 1 changesets with 1 changes to 1 files
305 searching for changes
305 searching for changes
306 adding changesets
306 adding changesets
307 adding manifests
307 adding manifests
308 adding file changes
308 adding file changes
309 added 1 changesets with 1 changes to 1 files
309 added 1 changesets with 1 changes to 1 files
310
310
311 push -f
311 push -f
312
312
313 $ echo bah > s/a
313 $ echo bah > s/a
314 $ hg ci -m12
314 $ hg ci -m12
315 committing subrepository s
315 committing subrepository s
316 $ hg push
316 $ hg push
317 pushing to $TESTTMP/t (glob)
317 pushing to $TESTTMP/t (glob)
318 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
318 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
319 searching for changes
319 searching for changes
320 no changes found
320 no changes found
321 pushing subrepo s to $TESTTMP/t/s (glob)
321 pushing subrepo s to $TESTTMP/t/s (glob)
322 searching for changes
322 searching for changes
323 abort: push creates new remote head 12a213df6fa9!
323 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
324 (did you forget to merge? use push -f to force)
324 (did you forget to merge? use push -f to force)
325 [255]
325 [255]
326 $ hg push -f
326 $ hg push -f
327 pushing to $TESTTMP/t (glob)
327 pushing to $TESTTMP/t (glob)
328 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
328 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
329 searching for changes
329 searching for changes
330 no changes found
330 no changes found
331 pushing subrepo s to $TESTTMP/t/s (glob)
331 pushing subrepo s to $TESTTMP/t/s (glob)
332 searching for changes
332 searching for changes
333 adding changesets
333 adding changesets
334 adding manifests
334 adding manifests
335 adding file changes
335 adding file changes
336 added 1 changesets with 1 changes to 1 files (+1 heads)
336 added 1 changesets with 1 changes to 1 files (+1 heads)
337 pushing subrepo t to $TESTTMP/t/t (glob)
337 pushing subrepo t to $TESTTMP/t/t (glob)
338 searching for changes
338 searching for changes
339 no changes found
339 no changes found
340 searching for changes
340 searching for changes
341 adding changesets
341 adding changesets
342 adding manifests
342 adding manifests
343 adding file changes
343 adding file changes
344 added 1 changesets with 1 changes to 1 files
344 added 1 changesets with 1 changes to 1 files
345
345
346 update
346 update
347
347
348 $ cd ../t
348 $ cd ../t
349 $ hg up -C # discard our earlier merge
349 $ hg up -C # discard our earlier merge
350 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
350 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 $ echo blah > t/t
351 $ echo blah > t/t
352 $ hg ci -m13
352 $ hg ci -m13
353 committing subrepository t
353 committing subrepository t
354
354
355 pull
355 pull
356
356
357 $ cd ../tc
357 $ cd ../tc
358 $ hg pull
358 $ hg pull
359 pulling from $TESTTMP/t (glob)
359 pulling from $TESTTMP/t (glob)
360 searching for changes
360 searching for changes
361 adding changesets
361 adding changesets
362 adding manifests
362 adding manifests
363 adding file changes
363 adding file changes
364 added 1 changesets with 1 changes to 1 files
364 added 1 changesets with 1 changes to 1 files
365 (run 'hg update' to get a working copy)
365 (run 'hg update' to get a working copy)
366
366
367 should pull t
367 should pull t
368
368
369 $ hg up
369 $ hg up
370 pulling subrepo t from $TESTTMP/t/t (glob)
370 pulling subrepo t from $TESTTMP/t/t (glob)
371 searching for changes
371 searching for changes
372 adding changesets
372 adding changesets
373 adding manifests
373 adding manifests
374 adding file changes
374 adding file changes
375 added 1 changesets with 1 changes to 1 files
375 added 1 changesets with 1 changes to 1 files
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 $ cat t/t
377 $ cat t/t
378 blah
378 blah
379
379
380 bogus subrepo path aborts
380 bogus subrepo path aborts
381
381
382 $ echo 'bogus=[boguspath' >> .hgsub
382 $ echo 'bogus=[boguspath' >> .hgsub
383 $ hg ci -m 'bogus subrepo path'
383 $ hg ci -m 'bogus subrepo path'
384 abort: missing ] in subrepo source
384 abort: missing ] in subrepo source
385 [255]
385 [255]
386
386
387 Issue1986: merge aborts when trying to merge a subrepo that
387 Issue1986: merge aborts when trying to merge a subrepo that
388 shouldn't need merging
388 shouldn't need merging
389
389
390 # subrepo layout
390 # subrepo layout
391 #
391 #
392 # o 5 br
392 # o 5 br
393 # /|
393 # /|
394 # o | 4 default
394 # o | 4 default
395 # | |
395 # | |
396 # | o 3 br
396 # | o 3 br
397 # |/|
397 # |/|
398 # o | 2 default
398 # o | 2 default
399 # | |
399 # | |
400 # | o 1 br
400 # | o 1 br
401 # |/
401 # |/
402 # o 0 default
402 # o 0 default
403
403
404 $ cd ..
404 $ cd ..
405 $ rm -rf sub
405 $ rm -rf sub
406 $ hg init main
406 $ hg init main
407 $ cd main
407 $ cd main
408 $ hg init s
408 $ hg init s
409 $ cd s
409 $ cd s
410 $ echo a > a
410 $ echo a > a
411 $ hg ci -Am1
411 $ hg ci -Am1
412 adding a
412 adding a
413 $ hg branch br
413 $ hg branch br
414 marked working directory as branch br
414 marked working directory as branch br
415 (branches are permanent and global, did you want a bookmark?)
415 (branches are permanent and global, did you want a bookmark?)
416 $ echo a >> a
416 $ echo a >> a
417 $ hg ci -m1
417 $ hg ci -m1
418 $ hg up default
418 $ hg up default
419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 $ echo b > b
420 $ echo b > b
421 $ hg ci -Am1
421 $ hg ci -Am1
422 adding b
422 adding b
423 $ hg up br
423 $ hg up br
424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
425 $ hg merge tip
425 $ hg merge tip
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 (branch merge, don't forget to commit)
427 (branch merge, don't forget to commit)
428 $ hg ci -m1
428 $ hg ci -m1
429 $ hg up 2
429 $ hg up 2
430 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
430 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 $ echo c > c
431 $ echo c > c
432 $ hg ci -Am1
432 $ hg ci -Am1
433 adding c
433 adding c
434 $ hg up 3
434 $ hg up 3
435 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
435 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
436 $ hg merge 4
436 $ hg merge 4
437 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 (branch merge, don't forget to commit)
438 (branch merge, don't forget to commit)
439 $ hg ci -m1
439 $ hg ci -m1
440
440
441 # main repo layout:
441 # main repo layout:
442 #
442 #
443 # * <-- try to merge default into br again
443 # * <-- try to merge default into br again
444 # .`|
444 # .`|
445 # . o 5 br --> substate = 5
445 # . o 5 br --> substate = 5
446 # . |
446 # . |
447 # o | 4 default --> substate = 4
447 # o | 4 default --> substate = 4
448 # | |
448 # | |
449 # | o 3 br --> substate = 2
449 # | o 3 br --> substate = 2
450 # |/|
450 # |/|
451 # o | 2 default --> substate = 2
451 # o | 2 default --> substate = 2
452 # | |
452 # | |
453 # | o 1 br --> substate = 3
453 # | o 1 br --> substate = 3
454 # |/
454 # |/
455 # o 0 default --> substate = 2
455 # o 0 default --> substate = 2
456
456
457 $ cd ..
457 $ cd ..
458 $ echo 's = s' > .hgsub
458 $ echo 's = s' > .hgsub
459 $ hg -R s up 2
459 $ hg -R s up 2
460 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
460 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
461 $ hg ci -Am1
461 $ hg ci -Am1
462 adding .hgsub
462 adding .hgsub
463 $ hg branch br
463 $ hg branch br
464 marked working directory as branch br
464 marked working directory as branch br
465 (branches are permanent and global, did you want a bookmark?)
465 (branches are permanent and global, did you want a bookmark?)
466 $ echo b > b
466 $ echo b > b
467 $ hg -R s up 3
467 $ hg -R s up 3
468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 $ hg ci -Am1
469 $ hg ci -Am1
470 adding b
470 adding b
471 $ hg up default
471 $ hg up default
472 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
472 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
473 $ echo c > c
473 $ echo c > c
474 $ hg ci -Am1
474 $ hg ci -Am1
475 adding c
475 adding c
476 $ hg up 1
476 $ hg up 1
477 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
477 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 $ hg merge 2
478 $ hg merge 2
479 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
479 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 (branch merge, don't forget to commit)
480 (branch merge, don't forget to commit)
481 $ hg ci -m1
481 $ hg ci -m1
482 $ hg up 2
482 $ hg up 2
483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 $ hg -R s up 4
484 $ hg -R s up 4
485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 $ echo d > d
486 $ echo d > d
487 $ hg ci -Am1
487 $ hg ci -Am1
488 adding d
488 adding d
489 $ hg up 3
489 $ hg up 3
490 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
490 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
491 $ hg -R s up 5
491 $ hg -R s up 5
492 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
492 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
493 $ echo e > e
493 $ echo e > e
494 $ hg ci -Am1
494 $ hg ci -Am1
495 adding e
495 adding e
496
496
497 $ hg up 5
497 $ hg up 5
498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 $ hg merge 4 # try to merge default into br again
499 $ hg merge 4 # try to merge default into br again
500 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
500 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 (branch merge, don't forget to commit)
501 (branch merge, don't forget to commit)
502 $ cd ..
502 $ cd ..
503
503
504 test subrepo delete from .hgsubstate
504 test subrepo delete from .hgsubstate
505
505
506 $ hg init testdelete
506 $ hg init testdelete
507 $ mkdir testdelete/nested testdelete/nested2
507 $ mkdir testdelete/nested testdelete/nested2
508 $ hg init testdelete/nested
508 $ hg init testdelete/nested
509 $ hg init testdelete/nested2
509 $ hg init testdelete/nested2
510 $ echo test > testdelete/nested/foo
510 $ echo test > testdelete/nested/foo
511 $ echo test > testdelete/nested2/foo
511 $ echo test > testdelete/nested2/foo
512 $ hg -R testdelete/nested add
512 $ hg -R testdelete/nested add
513 adding testdelete/nested/foo (glob)
513 adding testdelete/nested/foo (glob)
514 $ hg -R testdelete/nested2 add
514 $ hg -R testdelete/nested2 add
515 adding testdelete/nested2/foo (glob)
515 adding testdelete/nested2/foo (glob)
516 $ hg -R testdelete/nested ci -m test
516 $ hg -R testdelete/nested ci -m test
517 $ hg -R testdelete/nested2 ci -m test
517 $ hg -R testdelete/nested2 ci -m test
518 $ echo nested = nested > testdelete/.hgsub
518 $ echo nested = nested > testdelete/.hgsub
519 $ echo nested2 = nested2 >> testdelete/.hgsub
519 $ echo nested2 = nested2 >> testdelete/.hgsub
520 $ hg -R testdelete add
520 $ hg -R testdelete add
521 adding testdelete/.hgsub (glob)
521 adding testdelete/.hgsub (glob)
522 $ hg -R testdelete ci -m "nested 1 & 2 added"
522 $ hg -R testdelete ci -m "nested 1 & 2 added"
523 $ echo nested = nested > testdelete/.hgsub
523 $ echo nested = nested > testdelete/.hgsub
524 $ hg -R testdelete ci -m "nested 2 deleted"
524 $ hg -R testdelete ci -m "nested 2 deleted"
525 $ cat testdelete/.hgsubstate
525 $ cat testdelete/.hgsubstate
526 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
526 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
527 $ hg -R testdelete remove testdelete/.hgsub
527 $ hg -R testdelete remove testdelete/.hgsub
528 $ hg -R testdelete ci -m ".hgsub deleted"
528 $ hg -R testdelete ci -m ".hgsub deleted"
529 $ cat testdelete/.hgsubstate
529 $ cat testdelete/.hgsubstate
530 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
530 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
531
531
532 test repository cloning
532 test repository cloning
533
533
534 $ mkdir mercurial mercurial2
534 $ mkdir mercurial mercurial2
535 $ hg init nested_absolute
535 $ hg init nested_absolute
536 $ echo test > nested_absolute/foo
536 $ echo test > nested_absolute/foo
537 $ hg -R nested_absolute add
537 $ hg -R nested_absolute add
538 adding nested_absolute/foo (glob)
538 adding nested_absolute/foo (glob)
539 $ hg -R nested_absolute ci -mtest
539 $ hg -R nested_absolute ci -mtest
540 $ cd mercurial
540 $ cd mercurial
541 $ hg init nested_relative
541 $ hg init nested_relative
542 $ echo test2 > nested_relative/foo2
542 $ echo test2 > nested_relative/foo2
543 $ hg -R nested_relative add
543 $ hg -R nested_relative add
544 adding nested_relative/foo2 (glob)
544 adding nested_relative/foo2 (glob)
545 $ hg -R nested_relative ci -mtest2
545 $ hg -R nested_relative ci -mtest2
546 $ hg init main
546 $ hg init main
547 $ echo "nested_relative = ../nested_relative" > main/.hgsub
547 $ echo "nested_relative = ../nested_relative" > main/.hgsub
548 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
548 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
549 $ hg -R main add
549 $ hg -R main add
550 adding main/.hgsub (glob)
550 adding main/.hgsub (glob)
551 $ hg -R main ci -m "add subrepos"
551 $ hg -R main ci -m "add subrepos"
552 $ cd ..
552 $ cd ..
553 $ hg clone mercurial/main mercurial2/main
553 $ hg clone mercurial/main mercurial2/main
554 updating to branch default
554 updating to branch default
555 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
555 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
556 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
557 > mercurial2/main/nested_relative/.hg/hgrc
557 > mercurial2/main/nested_relative/.hg/hgrc
558 [paths]
558 [paths]
559 default = $TESTTMP/mercurial/nested_absolute
559 default = $TESTTMP/mercurial/nested_absolute
560 [paths]
560 [paths]
561 default = $TESTTMP/mercurial/nested_relative
561 default = $TESTTMP/mercurial/nested_relative
562 $ rm -rf mercurial mercurial2
562 $ rm -rf mercurial mercurial2
563
563
564 Issue1977: multirepo push should fail if subrepo push fails
564 Issue1977: multirepo push should fail if subrepo push fails
565
565
566 $ hg init repo
566 $ hg init repo
567 $ hg init repo/s
567 $ hg init repo/s
568 $ echo a > repo/s/a
568 $ echo a > repo/s/a
569 $ hg -R repo/s ci -Am0
569 $ hg -R repo/s ci -Am0
570 adding a
570 adding a
571 $ echo s = s > repo/.hgsub
571 $ echo s = s > repo/.hgsub
572 $ hg -R repo ci -Am1
572 $ hg -R repo ci -Am1
573 adding .hgsub
573 adding .hgsub
574 $ hg clone repo repo2
574 $ hg clone repo repo2
575 updating to branch default
575 updating to branch default
576 cloning subrepo s from $TESTTMP/repo/s (glob)
576 cloning subrepo s from $TESTTMP/repo/s (glob)
577 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
577 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 $ hg -q -R repo2 pull -u
578 $ hg -q -R repo2 pull -u
579 $ echo 1 > repo2/s/a
579 $ echo 1 > repo2/s/a
580 $ hg -R repo2/s ci -m2
580 $ hg -R repo2/s ci -m2
581 $ hg -q -R repo2/s push
581 $ hg -q -R repo2/s push
582 $ hg -R repo2/s up -C 0
582 $ hg -R repo2/s up -C 0
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 $ echo 2 > repo2/s/b
584 $ echo 2 > repo2/s/b
585 $ hg -R repo2/s ci -m3 -A
585 $ hg -R repo2/s ci -m3 -A
586 adding b
586 adding b
587 created new head
587 created new head
588 $ hg -R repo2 ci -m3
588 $ hg -R repo2 ci -m3
589 $ hg -q -R repo2 push
589 $ hg -q -R repo2 push
590 abort: push creates new remote head cc505f09a8b2!
590 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
591 (did you forget to merge? use push -f to force)
591 (did you forget to merge? use push -f to force)
592 [255]
592 [255]
593 $ hg -R repo update
593 $ hg -R repo update
594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595
595
596 test if untracked file is not overwritten
596 test if untracked file is not overwritten
597
597
598 $ echo issue3276_ok > repo/s/b
598 $ echo issue3276_ok > repo/s/b
599 $ hg -R repo2 push -f -q
599 $ hg -R repo2 push -f -q
600 $ hg -R repo update
600 $ hg -R repo update
601 b: untracked file differs
601 b: untracked file differs
602 abort: untracked files in working directory differ from files in requested revision
602 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
603 [255]
603 [255]
604
604
605 $ cat repo/s/b
605 $ cat repo/s/b
606 issue3276_ok
606 issue3276_ok
607 $ rm repo/s/b
607 $ rm repo/s/b
608 $ hg -R repo revert --all
608 $ hg -R repo revert --all
609 reverting repo/.hgsubstate (glob)
609 reverting repo/.hgsubstate (glob)
610 reverting subrepo s
610 reverting subrepo s
611 $ hg -R repo update
611 $ hg -R repo update
612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 $ cat repo/s/b
613 $ cat repo/s/b
614 2
614 2
615 $ rm -rf repo2 repo
615 $ rm -rf repo2 repo
616
616
617
617
618 Issue1852 subrepos with relative paths always push/pull relative to default
618 Issue1852 subrepos with relative paths always push/pull relative to default
619
619
620 Prepare a repo with subrepo
620 Prepare a repo with subrepo
621
621
622 $ hg init issue1852a
622 $ hg init issue1852a
623 $ cd issue1852a
623 $ cd issue1852a
624 $ hg init sub/repo
624 $ hg init sub/repo
625 $ echo test > sub/repo/foo
625 $ echo test > sub/repo/foo
626 $ hg -R sub/repo add sub/repo/foo
626 $ hg -R sub/repo add sub/repo/foo
627 $ echo sub/repo = sub/repo > .hgsub
627 $ echo sub/repo = sub/repo > .hgsub
628 $ hg add .hgsub
628 $ hg add .hgsub
629 $ hg ci -mtest
629 $ hg ci -mtest
630 committing subrepository sub/repo (glob)
630 committing subrepository sub/repo (glob)
631 $ echo test >> sub/repo/foo
631 $ echo test >> sub/repo/foo
632 $ hg ci -mtest
632 $ hg ci -mtest
633 committing subrepository sub/repo (glob)
633 committing subrepository sub/repo (glob)
634 $ cd ..
634 $ cd ..
635
635
636 Create repo without default path, pull top repo, and see what happens on update
636 Create repo without default path, pull top repo, and see what happens on update
637
637
638 $ hg init issue1852b
638 $ hg init issue1852b
639 $ hg -R issue1852b pull issue1852a
639 $ hg -R issue1852b pull issue1852a
640 pulling from issue1852a
640 pulling from issue1852a
641 requesting all changes
641 requesting all changes
642 adding changesets
642 adding changesets
643 adding manifests
643 adding manifests
644 adding file changes
644 adding file changes
645 added 2 changesets with 3 changes to 2 files
645 added 2 changesets with 3 changes to 2 files
646 (run 'hg update' to get a working copy)
646 (run 'hg update' to get a working copy)
647 $ hg -R issue1852b update
647 $ hg -R issue1852b update
648 abort: default path for subrepository sub/repo not found (glob)
648 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
649 [255]
649 [255]
650
650
651 Pull -u now doesn't help
651 Pull -u now doesn't help
652
652
653 $ hg -R issue1852b pull -u issue1852a
653 $ hg -R issue1852b pull -u issue1852a
654 pulling from issue1852a
654 pulling from issue1852a
655 searching for changes
655 searching for changes
656 no changes found
656 no changes found
657
657
658 Try the same, but with pull -u
658 Try the same, but with pull -u
659
659
660 $ hg init issue1852c
660 $ hg init issue1852c
661 $ hg -R issue1852c pull -r0 -u issue1852a
661 $ hg -R issue1852c pull -r0 -u issue1852a
662 pulling from issue1852a
662 pulling from issue1852a
663 adding changesets
663 adding changesets
664 adding manifests
664 adding manifests
665 adding file changes
665 adding file changes
666 added 1 changesets with 2 changes to 2 files
666 added 1 changesets with 2 changes to 2 files
667 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
667 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
668 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
668 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
669
669
670 Try to push from the other side
670 Try to push from the other side
671
671
672 $ hg -R issue1852a push `pwd`/issue1852c
672 $ hg -R issue1852a push `pwd`/issue1852c
673 pushing to $TESTTMP/issue1852c
673 pushing to $TESTTMP/issue1852c
674 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
674 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
675 searching for changes
675 searching for changes
676 no changes found
676 no changes found
677 searching for changes
677 searching for changes
678 adding changesets
678 adding changesets
679 adding manifests
679 adding manifests
680 adding file changes
680 adding file changes
681 added 1 changesets with 1 changes to 1 files
681 added 1 changesets with 1 changes to 1 files
682
682
683 Incoming and outgoing should not use the default path:
683 Incoming and outgoing should not use the default path:
684
684
685 $ hg clone -q issue1852a issue1852d
685 $ hg clone -q issue1852a issue1852d
686 $ hg -R issue1852d outgoing --subrepos issue1852c
686 $ hg -R issue1852d outgoing --subrepos issue1852c
687 comparing with issue1852c
687 comparing with issue1852c
688 searching for changes
688 searching for changes
689 no changes found
689 no changes found
690 comparing with issue1852c/sub/repo
690 comparing with issue1852c/sub/repo
691 searching for changes
691 searching for changes
692 no changes found
692 no changes found
693 [1]
693 [1]
694 $ hg -R issue1852d incoming --subrepos issue1852c
694 $ hg -R issue1852d incoming --subrepos issue1852c
695 comparing with issue1852c
695 comparing with issue1852c
696 searching for changes
696 searching for changes
697 no changes found
697 no changes found
698 comparing with issue1852c/sub/repo
698 comparing with issue1852c/sub/repo
699 searching for changes
699 searching for changes
700 no changes found
700 no changes found
701 [1]
701 [1]
702
702
703 Check status of files when none of them belong to the first
703 Check status of files when none of them belong to the first
704 subrepository:
704 subrepository:
705
705
706 $ hg init subrepo-status
706 $ hg init subrepo-status
707 $ cd subrepo-status
707 $ cd subrepo-status
708 $ hg init subrepo-1
708 $ hg init subrepo-1
709 $ hg init subrepo-2
709 $ hg init subrepo-2
710 $ cd subrepo-2
710 $ cd subrepo-2
711 $ touch file
711 $ touch file
712 $ hg add file
712 $ hg add file
713 $ cd ..
713 $ cd ..
714 $ echo subrepo-1 = subrepo-1 > .hgsub
714 $ echo subrepo-1 = subrepo-1 > .hgsub
715 $ echo subrepo-2 = subrepo-2 >> .hgsub
715 $ echo subrepo-2 = subrepo-2 >> .hgsub
716 $ hg add .hgsub
716 $ hg add .hgsub
717 $ hg ci -m 'Added subrepos'
717 $ hg ci -m 'Added subrepos'
718 committing subrepository subrepo-2
718 committing subrepository subrepo-2
719 $ hg st subrepo-2/file
719 $ hg st subrepo-2/file
720
720
721 Check that share works with subrepo
721 Check that share works with subrepo
722 $ hg --config extensions.share= share . ../shared
722 $ hg --config extensions.share= share . ../shared
723 updating working directory
723 updating working directory
724 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
724 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
725 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
725 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 $ test -f ../shared/subrepo-1/.hg/sharedpath
726 $ test -f ../shared/subrepo-1/.hg/sharedpath
727 [1]
727 [1]
728
728
729 Check hg update --clean
729 Check hg update --clean
730 $ cd $TESTTMP/t
730 $ cd $TESTTMP/t
731 $ rm -r t/t.orig
731 $ rm -r t/t.orig
732 $ hg status -S --all
732 $ hg status -S --all
733 C .hgsub
733 C .hgsub
734 C .hgsubstate
734 C .hgsubstate
735 C a
735 C a
736 C s/.hgsub
736 C s/.hgsub
737 C s/.hgsubstate
737 C s/.hgsubstate
738 C s/a
738 C s/a
739 C s/ss/a
739 C s/ss/a
740 C t/t
740 C t/t
741 $ echo c1 > s/a
741 $ echo c1 > s/a
742 $ cd s
742 $ cd s
743 $ echo c1 > b
743 $ echo c1 > b
744 $ echo c1 > c
744 $ echo c1 > c
745 $ hg add b
745 $ hg add b
746 $ cd ..
746 $ cd ..
747 $ hg status -S
747 $ hg status -S
748 M s/a
748 M s/a
749 A s/b
749 A s/b
750 ? s/c
750 ? s/c
751 $ hg update -C
751 $ hg update -C
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 $ hg status -S
753 $ hg status -S
754 ? s/b
754 ? s/b
755 ? s/c
755 ? s/c
756
756
757 Sticky subrepositories, no changes
757 Sticky subrepositories, no changes
758 $ cd $TESTTMP/t
758 $ cd $TESTTMP/t
759 $ hg id
759 $ hg id
760 925c17564ef8 tip
760 925c17564ef8 tip
761 $ hg -R s id
761 $ hg -R s id
762 12a213df6fa9 tip
762 12a213df6fa9 tip
763 $ hg -R t id
763 $ hg -R t id
764 52c0adc0515a tip
764 52c0adc0515a tip
765 $ hg update 11
765 $ hg update 11
766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
767 $ hg id
767 $ hg id
768 365661e5936a
768 365661e5936a
769 $ hg -R s id
769 $ hg -R s id
770 fc627a69481f
770 fc627a69481f
771 $ hg -R t id
771 $ hg -R t id
772 e95bcfa18a35
772 e95bcfa18a35
773
773
774 Sticky subrepositorys, file changes
774 Sticky subrepositorys, file changes
775 $ touch s/f1
775 $ touch s/f1
776 $ touch t/f1
776 $ touch t/f1
777 $ hg add -S s/f1
777 $ hg add -S s/f1
778 $ hg add -S t/f1
778 $ hg add -S t/f1
779 $ hg id
779 $ hg id
780 365661e5936a+
780 365661e5936a+
781 $ hg -R s id
781 $ hg -R s id
782 fc627a69481f+
782 fc627a69481f+
783 $ hg -R t id
783 $ hg -R t id
784 e95bcfa18a35+
784 e95bcfa18a35+
785 $ hg update tip
785 $ hg update tip
786 subrepository sources for s differ
786 subrepository sources for s differ
787 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
787 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
788 l
788 l
789 subrepository sources for t differ
789 subrepository sources for t differ
790 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
790 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
791 l
791 l
792 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
792 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
793 $ hg id
793 $ hg id
794 925c17564ef8+ tip
794 925c17564ef8+ tip
795 $ hg -R s id
795 $ hg -R s id
796 fc627a69481f+
796 fc627a69481f+
797 $ hg -R t id
797 $ hg -R t id
798 e95bcfa18a35+
798 e95bcfa18a35+
799 $ hg update --clean tip
799 $ hg update --clean tip
800 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
800 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
801
801
802 Sticky subrepository, revision updates
802 Sticky subrepository, revision updates
803 $ hg id
803 $ hg id
804 925c17564ef8 tip
804 925c17564ef8 tip
805 $ hg -R s id
805 $ hg -R s id
806 12a213df6fa9 tip
806 12a213df6fa9 tip
807 $ hg -R t id
807 $ hg -R t id
808 52c0adc0515a tip
808 52c0adc0515a tip
809 $ cd s
809 $ cd s
810 $ hg update -r -2
810 $ hg update -r -2
811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 $ cd ../t
812 $ cd ../t
813 $ hg update -r 2
813 $ hg update -r 2
814 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
814 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
815 $ cd ..
815 $ cd ..
816 $ hg update 10
816 $ hg update 10
817 subrepository sources for t differ (in checked out version)
817 subrepository sources for t differ (in checked out version)
818 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
818 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
819 l
819 l
820 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
820 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 $ hg id
821 $ hg id
822 e45c8b14af55+
822 e45c8b14af55+
823 $ hg -R s id
823 $ hg -R s id
824 02dcf1d70411
824 02dcf1d70411
825 $ hg -R t id
825 $ hg -R t id
826 7af322bc1198
826 7af322bc1198
827
827
828 Sticky subrepository, file changes and revision updates
828 Sticky subrepository, file changes and revision updates
829 $ touch s/f1
829 $ touch s/f1
830 $ touch t/f1
830 $ touch t/f1
831 $ hg add -S s/f1
831 $ hg add -S s/f1
832 $ hg add -S t/f1
832 $ hg add -S t/f1
833 $ hg id
833 $ hg id
834 e45c8b14af55+
834 e45c8b14af55+
835 $ hg -R s id
835 $ hg -R s id
836 02dcf1d70411+
836 02dcf1d70411+
837 $ hg -R t id
837 $ hg -R t id
838 7af322bc1198+
838 7af322bc1198+
839 $ hg update tip
839 $ hg update tip
840 subrepository sources for s differ
840 subrepository sources for s differ
841 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
841 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
842 l
842 l
843 subrepository sources for t differ
843 subrepository sources for t differ
844 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
844 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
845 l
845 l
846 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
846 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
847 $ hg id
847 $ hg id
848 925c17564ef8+ tip
848 925c17564ef8+ tip
849 $ hg -R s id
849 $ hg -R s id
850 02dcf1d70411+
850 02dcf1d70411+
851 $ hg -R t id
851 $ hg -R t id
852 7af322bc1198+
852 7af322bc1198+
853
853
854 Sticky repository, update --clean
854 Sticky repository, update --clean
855 $ hg update --clean tip
855 $ hg update --clean tip
856 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
856 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
857 $ hg id
857 $ hg id
858 925c17564ef8 tip
858 925c17564ef8 tip
859 $ hg -R s id
859 $ hg -R s id
860 12a213df6fa9 tip
860 12a213df6fa9 tip
861 $ hg -R t id
861 $ hg -R t id
862 52c0adc0515a tip
862 52c0adc0515a tip
863
863
864 Test subrepo already at intended revision:
864 Test subrepo already at intended revision:
865 $ cd s
865 $ cd s
866 $ hg update fc627a69481f
866 $ hg update fc627a69481f
867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
868 $ cd ..
868 $ cd ..
869 $ hg update 11
869 $ hg update 11
870 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
870 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
872 $ hg id -n
872 $ hg id -n
873 11+
873 11+
874 $ hg -R s id
874 $ hg -R s id
875 fc627a69481f
875 fc627a69481f
876 $ hg -R t id
876 $ hg -R t id
877 e95bcfa18a35
877 e95bcfa18a35
878
878
879 Test that removing .hgsubstate doesn't break anything:
879 Test that removing .hgsubstate doesn't break anything:
880
880
881 $ hg rm -f .hgsubstate
881 $ hg rm -f .hgsubstate
882 $ hg ci -mrm
882 $ hg ci -mrm
883 nothing changed
883 nothing changed
884 [1]
884 [1]
885 $ hg log -vr tip
885 $ hg log -vr tip
886 changeset: 13:925c17564ef8
886 changeset: 13:925c17564ef8
887 tag: tip
887 tag: tip
888 user: test
888 user: test
889 date: Thu Jan 01 00:00:00 1970 +0000
889 date: Thu Jan 01 00:00:00 1970 +0000
890 files: .hgsubstate
890 files: .hgsubstate
891 description:
891 description:
892 13
892 13
893
893
894
894
895
895
896 Test that removing .hgsub removes .hgsubstate:
896 Test that removing .hgsub removes .hgsubstate:
897
897
898 $ hg rm .hgsub
898 $ hg rm .hgsub
899 $ hg ci -mrm2
899 $ hg ci -mrm2
900 created new head
900 created new head
901 $ hg log -vr tip
901 $ hg log -vr tip
902 changeset: 14:2400bccd50af
902 changeset: 14:2400bccd50af
903 tag: tip
903 tag: tip
904 parent: 11:365661e5936a
904 parent: 11:365661e5936a
905 user: test
905 user: test
906 date: Thu Jan 01 00:00:00 1970 +0000
906 date: Thu Jan 01 00:00:00 1970 +0000
907 files: .hgsub .hgsubstate
907 files: .hgsub .hgsubstate
908 description:
908 description:
909 rm2
909 rm2
910
910
911
911
912 Test issue3153: diff -S with deleted subrepos
912 Test issue3153: diff -S with deleted subrepos
913
913
914 $ hg diff --nodates -S -c .
914 $ hg diff --nodates -S -c .
915 diff -r 365661e5936a -r 2400bccd50af .hgsub
915 diff -r 365661e5936a -r 2400bccd50af .hgsub
916 --- a/.hgsub
916 --- a/.hgsub
917 +++ /dev/null
917 +++ /dev/null
918 @@ -1,2 +0,0 @@
918 @@ -1,2 +0,0 @@
919 -s = s
919 -s = s
920 -t = t
920 -t = t
921 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
921 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
922 --- a/.hgsubstate
922 --- a/.hgsubstate
923 +++ /dev/null
923 +++ /dev/null
924 @@ -1,2 +0,0 @@
924 @@ -1,2 +0,0 @@
925 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
925 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
926 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
926 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
927
927
928 Test behavior of add for explicit path in subrepo:
928 Test behavior of add for explicit path in subrepo:
929 $ cd ..
929 $ cd ..
930 $ hg init explicit
930 $ hg init explicit
931 $ cd explicit
931 $ cd explicit
932 $ echo s = s > .hgsub
932 $ echo s = s > .hgsub
933 $ hg add .hgsub
933 $ hg add .hgsub
934 $ hg init s
934 $ hg init s
935 $ hg ci -m0
935 $ hg ci -m0
936 Adding with an explicit path in a subrepo adds the file
936 Adding with an explicit path in a subrepo adds the file
937 $ echo c1 > f1
937 $ echo c1 > f1
938 $ echo c2 > s/f2
938 $ echo c2 > s/f2
939 $ hg st -S
939 $ hg st -S
940 ? f1
940 ? f1
941 ? s/f2
941 ? s/f2
942 $ hg add s/f2
942 $ hg add s/f2
943 $ hg st -S
943 $ hg st -S
944 A s/f2
944 A s/f2
945 ? f1
945 ? f1
946 $ hg ci -R s -m0
946 $ hg ci -R s -m0
947 $ hg ci -Am1
947 $ hg ci -Am1
948 adding f1
948 adding f1
949 Adding with an explicit path in a subrepo with -S has the same behavior
949 Adding with an explicit path in a subrepo with -S has the same behavior
950 $ echo c3 > f3
950 $ echo c3 > f3
951 $ echo c4 > s/f4
951 $ echo c4 > s/f4
952 $ hg st -S
952 $ hg st -S
953 ? f3
953 ? f3
954 ? s/f4
954 ? s/f4
955 $ hg add -S s/f4
955 $ hg add -S s/f4
956 $ hg st -S
956 $ hg st -S
957 A s/f4
957 A s/f4
958 ? f3
958 ? f3
959 $ hg ci -R s -m1
959 $ hg ci -R s -m1
960 $ hg ci -Ama2
960 $ hg ci -Ama2
961 adding f3
961 adding f3
962 Adding without a path or pattern silently ignores subrepos
962 Adding without a path or pattern silently ignores subrepos
963 $ echo c5 > f5
963 $ echo c5 > f5
964 $ echo c6 > s/f6
964 $ echo c6 > s/f6
965 $ echo c7 > s/f7
965 $ echo c7 > s/f7
966 $ hg st -S
966 $ hg st -S
967 ? f5
967 ? f5
968 ? s/f6
968 ? s/f6
969 ? s/f7
969 ? s/f7
970 $ hg add
970 $ hg add
971 adding f5
971 adding f5
972 $ hg st -S
972 $ hg st -S
973 A f5
973 A f5
974 ? s/f6
974 ? s/f6
975 ? s/f7
975 ? s/f7
976 $ hg ci -R s -Am2
976 $ hg ci -R s -Am2
977 adding f6
977 adding f6
978 adding f7
978 adding f7
979 $ hg ci -m3
979 $ hg ci -m3
980 Adding without a path or pattern with -S also adds files in subrepos
980 Adding without a path or pattern with -S also adds files in subrepos
981 $ echo c8 > f8
981 $ echo c8 > f8
982 $ echo c9 > s/f9
982 $ echo c9 > s/f9
983 $ echo c10 > s/f10
983 $ echo c10 > s/f10
984 $ hg st -S
984 $ hg st -S
985 ? f8
985 ? f8
986 ? s/f10
986 ? s/f10
987 ? s/f9
987 ? s/f9
988 $ hg add -S
988 $ hg add -S
989 adding f8
989 adding f8
990 adding s/f10 (glob)
990 adding s/f10 (glob)
991 adding s/f9 (glob)
991 adding s/f9 (glob)
992 $ hg st -S
992 $ hg st -S
993 A f8
993 A f8
994 A s/f10
994 A s/f10
995 A s/f9
995 A s/f9
996 $ hg ci -R s -m3
996 $ hg ci -R s -m3
997 $ hg ci -m4
997 $ hg ci -m4
998 Adding with a pattern silently ignores subrepos
998 Adding with a pattern silently ignores subrepos
999 $ echo c11 > fm11
999 $ echo c11 > fm11
1000 $ echo c12 > fn12
1000 $ echo c12 > fn12
1001 $ echo c13 > s/fm13
1001 $ echo c13 > s/fm13
1002 $ echo c14 > s/fn14
1002 $ echo c14 > s/fn14
1003 $ hg st -S
1003 $ hg st -S
1004 ? fm11
1004 ? fm11
1005 ? fn12
1005 ? fn12
1006 ? s/fm13
1006 ? s/fm13
1007 ? s/fn14
1007 ? s/fn14
1008 $ hg add 'glob:**fm*'
1008 $ hg add 'glob:**fm*'
1009 adding fm11
1009 adding fm11
1010 $ hg st -S
1010 $ hg st -S
1011 A fm11
1011 A fm11
1012 ? fn12
1012 ? fn12
1013 ? s/fm13
1013 ? s/fm13
1014 ? s/fn14
1014 ? s/fn14
1015 $ hg ci -R s -Am4
1015 $ hg ci -R s -Am4
1016 adding fm13
1016 adding fm13
1017 adding fn14
1017 adding fn14
1018 $ hg ci -Am5
1018 $ hg ci -Am5
1019 adding fn12
1019 adding fn12
1020 Adding with a pattern with -S also adds matches in subrepos
1020 Adding with a pattern with -S also adds matches in subrepos
1021 $ echo c15 > fm15
1021 $ echo c15 > fm15
1022 $ echo c16 > fn16
1022 $ echo c16 > fn16
1023 $ echo c17 > s/fm17
1023 $ echo c17 > s/fm17
1024 $ echo c18 > s/fn18
1024 $ echo c18 > s/fn18
1025 $ hg st -S
1025 $ hg st -S
1026 ? fm15
1026 ? fm15
1027 ? fn16
1027 ? fn16
1028 ? s/fm17
1028 ? s/fm17
1029 ? s/fn18
1029 ? s/fn18
1030 $ hg add -S 'glob:**fm*'
1030 $ hg add -S 'glob:**fm*'
1031 adding fm15
1031 adding fm15
1032 adding s/fm17 (glob)
1032 adding s/fm17 (glob)
1033 $ hg st -S
1033 $ hg st -S
1034 A fm15
1034 A fm15
1035 A s/fm17
1035 A s/fm17
1036 ? fn16
1036 ? fn16
1037 ? s/fn18
1037 ? s/fn18
1038 $ hg ci -R s -Am5
1038 $ hg ci -R s -Am5
1039 adding fn18
1039 adding fn18
1040 $ hg ci -Am6
1040 $ hg ci -Am6
1041 adding fn16
1041 adding fn16
1042
1042
1043 Test behavior of forget for explicit path in subrepo:
1043 Test behavior of forget for explicit path in subrepo:
1044 Forgetting an explicit path in a subrepo untracks the file
1044 Forgetting an explicit path in a subrepo untracks the file
1045 $ echo c19 > s/f19
1045 $ echo c19 > s/f19
1046 $ hg add s/f19
1046 $ hg add s/f19
1047 $ hg st -S
1047 $ hg st -S
1048 A s/f19
1048 A s/f19
1049 $ hg forget s/f19
1049 $ hg forget s/f19
1050 $ hg st -S
1050 $ hg st -S
1051 ? s/f19
1051 ? s/f19
1052 $ rm s/f19
1052 $ rm s/f19
1053 $ cd ..
1053 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now