##// END OF EJS Templates
hg: perform update after pulling during clone with share (issue5103)...
Gregory Szorc -
r28632:a2c2dd39 stable
parent child Browse files
Show More
@@ -1,931 +1,941
1 # hg.py - repository classes for mercurial
1 # hg.py - repository classes for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import errno
11 import errno
12 import os
12 import os
13 import shutil
13 import shutil
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import nullid
16 from .node import nullid
17
17
18 from . import (
18 from . import (
19 bookmarks,
19 bookmarks,
20 bundlerepo,
20 bundlerepo,
21 cmdutil,
21 cmdutil,
22 discovery,
22 discovery,
23 error,
23 error,
24 exchange,
24 exchange,
25 extensions,
25 extensions,
26 httppeer,
26 httppeer,
27 localrepo,
27 localrepo,
28 lock,
28 lock,
29 merge as mergemod,
29 merge as mergemod,
30 node,
30 node,
31 phases,
31 phases,
32 repoview,
32 repoview,
33 scmutil,
33 scmutil,
34 sshpeer,
34 sshpeer,
35 statichttprepo,
35 statichttprepo,
36 ui as uimod,
36 ui as uimod,
37 unionrepo,
37 unionrepo,
38 url,
38 url,
39 util,
39 util,
40 verify as verifymod,
40 verify as verifymod,
41 )
41 )
42
42
43 release = lock.release
43 release = lock.release
44
44
45 def _local(path):
45 def _local(path):
46 path = util.expandpath(util.urllocalpath(path))
46 path = util.expandpath(util.urllocalpath(path))
47 return (os.path.isfile(path) and bundlerepo or localrepo)
47 return (os.path.isfile(path) and bundlerepo or localrepo)
48
48
49 def addbranchrevs(lrepo, other, branches, revs):
49 def addbranchrevs(lrepo, other, branches, revs):
50 peer = other.peer() # a courtesy to callers using a localrepo for other
50 peer = other.peer() # a courtesy to callers using a localrepo for other
51 hashbranch, branches = branches
51 hashbranch, branches = branches
52 if not hashbranch and not branches:
52 if not hashbranch and not branches:
53 x = revs or None
53 x = revs or None
54 if util.safehasattr(revs, 'first'):
54 if util.safehasattr(revs, 'first'):
55 y = revs.first()
55 y = revs.first()
56 elif revs:
56 elif revs:
57 y = revs[0]
57 y = revs[0]
58 else:
58 else:
59 y = None
59 y = None
60 return x, y
60 return x, y
61 if revs:
61 if revs:
62 revs = list(revs)
62 revs = list(revs)
63 else:
63 else:
64 revs = []
64 revs = []
65
65
66 if not peer.capable('branchmap'):
66 if not peer.capable('branchmap'):
67 if branches:
67 if branches:
68 raise error.Abort(_("remote branch lookup not supported"))
68 raise error.Abort(_("remote branch lookup not supported"))
69 revs.append(hashbranch)
69 revs.append(hashbranch)
70 return revs, revs[0]
70 return revs, revs[0]
71 branchmap = peer.branchmap()
71 branchmap = peer.branchmap()
72
72
73 def primary(branch):
73 def primary(branch):
74 if branch == '.':
74 if branch == '.':
75 if not lrepo:
75 if not lrepo:
76 raise error.Abort(_("dirstate branch not accessible"))
76 raise error.Abort(_("dirstate branch not accessible"))
77 branch = lrepo.dirstate.branch()
77 branch = lrepo.dirstate.branch()
78 if branch in branchmap:
78 if branch in branchmap:
79 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
79 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
80 return True
80 return True
81 else:
81 else:
82 return False
82 return False
83
83
84 for branch in branches:
84 for branch in branches:
85 if not primary(branch):
85 if not primary(branch):
86 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
86 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
87 if hashbranch:
87 if hashbranch:
88 if not primary(hashbranch):
88 if not primary(hashbranch):
89 revs.append(hashbranch)
89 revs.append(hashbranch)
90 return revs, revs[0]
90 return revs, revs[0]
91
91
92 def parseurl(path, branches=None):
92 def parseurl(path, branches=None):
93 '''parse url#branch, returning (url, (branch, branches))'''
93 '''parse url#branch, returning (url, (branch, branches))'''
94
94
95 u = util.url(path)
95 u = util.url(path)
96 branch = None
96 branch = None
97 if u.fragment:
97 if u.fragment:
98 branch = u.fragment
98 branch = u.fragment
99 u.fragment = None
99 u.fragment = None
100 return str(u), (branch, branches or [])
100 return str(u), (branch, branches or [])
101
101
102 schemes = {
102 schemes = {
103 'bundle': bundlerepo,
103 'bundle': bundlerepo,
104 'union': unionrepo,
104 'union': unionrepo,
105 'file': _local,
105 'file': _local,
106 'http': httppeer,
106 'http': httppeer,
107 'https': httppeer,
107 'https': httppeer,
108 'ssh': sshpeer,
108 'ssh': sshpeer,
109 'static-http': statichttprepo,
109 'static-http': statichttprepo,
110 }
110 }
111
111
112 def _peerlookup(path):
112 def _peerlookup(path):
113 u = util.url(path)
113 u = util.url(path)
114 scheme = u.scheme or 'file'
114 scheme = u.scheme or 'file'
115 thing = schemes.get(scheme) or schemes['file']
115 thing = schemes.get(scheme) or schemes['file']
116 try:
116 try:
117 return thing(path)
117 return thing(path)
118 except TypeError:
118 except TypeError:
119 # we can't test callable(thing) because 'thing' can be an unloaded
119 # we can't test callable(thing) because 'thing' can be an unloaded
120 # module that implements __call__
120 # module that implements __call__
121 if not util.safehasattr(thing, 'instance'):
121 if not util.safehasattr(thing, 'instance'):
122 raise
122 raise
123 return thing
123 return thing
124
124
125 def islocal(repo):
125 def islocal(repo):
126 '''return true if repo (or path pointing to repo) is local'''
126 '''return true if repo (or path pointing to repo) is local'''
127 if isinstance(repo, str):
127 if isinstance(repo, str):
128 try:
128 try:
129 return _peerlookup(repo).islocal(repo)
129 return _peerlookup(repo).islocal(repo)
130 except AttributeError:
130 except AttributeError:
131 return False
131 return False
132 return repo.local()
132 return repo.local()
133
133
134 def openpath(ui, path):
134 def openpath(ui, path):
135 '''open path with open if local, url.open if remote'''
135 '''open path with open if local, url.open if remote'''
136 pathurl = util.url(path, parsequery=False, parsefragment=False)
136 pathurl = util.url(path, parsequery=False, parsefragment=False)
137 if pathurl.islocal():
137 if pathurl.islocal():
138 return util.posixfile(pathurl.localpath(), 'rb')
138 return util.posixfile(pathurl.localpath(), 'rb')
139 else:
139 else:
140 return url.open(ui, path)
140 return url.open(ui, path)
141
141
142 # a list of (ui, repo) functions called for wire peer initialization
142 # a list of (ui, repo) functions called for wire peer initialization
143 wirepeersetupfuncs = []
143 wirepeersetupfuncs = []
144
144
145 def _peerorrepo(ui, path, create=False):
145 def _peerorrepo(ui, path, create=False):
146 """return a repository object for the specified path"""
146 """return a repository object for the specified path"""
147 obj = _peerlookup(path).instance(ui, path, create)
147 obj = _peerlookup(path).instance(ui, path, create)
148 ui = getattr(obj, "ui", ui)
148 ui = getattr(obj, "ui", ui)
149 for name, module in extensions.extensions(ui):
149 for name, module in extensions.extensions(ui):
150 hook = getattr(module, 'reposetup', None)
150 hook = getattr(module, 'reposetup', None)
151 if hook:
151 if hook:
152 hook(ui, obj)
152 hook(ui, obj)
153 if not obj.local():
153 if not obj.local():
154 for f in wirepeersetupfuncs:
154 for f in wirepeersetupfuncs:
155 f(ui, obj)
155 f(ui, obj)
156 return obj
156 return obj
157
157
158 def repository(ui, path='', create=False):
158 def repository(ui, path='', create=False):
159 """return a repository object for the specified path"""
159 """return a repository object for the specified path"""
160 peer = _peerorrepo(ui, path, create)
160 peer = _peerorrepo(ui, path, create)
161 repo = peer.local()
161 repo = peer.local()
162 if not repo:
162 if not repo:
163 raise error.Abort(_("repository '%s' is not local") %
163 raise error.Abort(_("repository '%s' is not local") %
164 (path or peer.url()))
164 (path or peer.url()))
165 return repo.filtered('visible')
165 return repo.filtered('visible')
166
166
167 def peer(uiorrepo, opts, path, create=False):
167 def peer(uiorrepo, opts, path, create=False):
168 '''return a repository peer for the specified path'''
168 '''return a repository peer for the specified path'''
169 rui = remoteui(uiorrepo, opts)
169 rui = remoteui(uiorrepo, opts)
170 return _peerorrepo(rui, path, create).peer()
170 return _peerorrepo(rui, path, create).peer()
171
171
172 def defaultdest(source):
172 def defaultdest(source):
173 '''return default destination of clone if none is given
173 '''return default destination of clone if none is given
174
174
175 >>> defaultdest('foo')
175 >>> defaultdest('foo')
176 'foo'
176 'foo'
177 >>> defaultdest('/foo/bar')
177 >>> defaultdest('/foo/bar')
178 'bar'
178 'bar'
179 >>> defaultdest('/')
179 >>> defaultdest('/')
180 ''
180 ''
181 >>> defaultdest('')
181 >>> defaultdest('')
182 ''
182 ''
183 >>> defaultdest('http://example.org/')
183 >>> defaultdest('http://example.org/')
184 ''
184 ''
185 >>> defaultdest('http://example.org/foo/')
185 >>> defaultdest('http://example.org/foo/')
186 'foo'
186 'foo'
187 '''
187 '''
188 path = util.url(source).path
188 path = util.url(source).path
189 if not path:
189 if not path:
190 return ''
190 return ''
191 return os.path.basename(os.path.normpath(path))
191 return os.path.basename(os.path.normpath(path))
192
192
193 def share(ui, source, dest=None, update=True, bookmarks=True):
193 def share(ui, source, dest=None, update=True, bookmarks=True):
194 '''create a shared repository'''
194 '''create a shared repository'''
195
195
196 if not islocal(source):
196 if not islocal(source):
197 raise error.Abort(_('can only share local repositories'))
197 raise error.Abort(_('can only share local repositories'))
198
198
199 if not dest:
199 if not dest:
200 dest = defaultdest(source)
200 dest = defaultdest(source)
201 else:
201 else:
202 dest = ui.expandpath(dest)
202 dest = ui.expandpath(dest)
203
203
204 if isinstance(source, str):
204 if isinstance(source, str):
205 origsource = ui.expandpath(source)
205 origsource = ui.expandpath(source)
206 source, branches = parseurl(origsource)
206 source, branches = parseurl(origsource)
207 srcrepo = repository(ui, source)
207 srcrepo = repository(ui, source)
208 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
208 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
209 else:
209 else:
210 srcrepo = source.local()
210 srcrepo = source.local()
211 origsource = source = srcrepo.url()
211 origsource = source = srcrepo.url()
212 checkout = None
212 checkout = None
213
213
214 sharedpath = srcrepo.sharedpath # if our source is already sharing
214 sharedpath = srcrepo.sharedpath # if our source is already sharing
215
215
216 destwvfs = scmutil.vfs(dest, realpath=True)
216 destwvfs = scmutil.vfs(dest, realpath=True)
217 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
217 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
218
218
219 if destvfs.lexists():
219 if destvfs.lexists():
220 raise error.Abort(_('destination already exists'))
220 raise error.Abort(_('destination already exists'))
221
221
222 if not destwvfs.isdir():
222 if not destwvfs.isdir():
223 destwvfs.mkdir()
223 destwvfs.mkdir()
224 destvfs.makedir()
224 destvfs.makedir()
225
225
226 requirements = ''
226 requirements = ''
227 try:
227 try:
228 requirements = srcrepo.vfs.read('requires')
228 requirements = srcrepo.vfs.read('requires')
229 except IOError as inst:
229 except IOError as inst:
230 if inst.errno != errno.ENOENT:
230 if inst.errno != errno.ENOENT:
231 raise
231 raise
232
232
233 requirements += 'shared\n'
233 requirements += 'shared\n'
234 destvfs.write('requires', requirements)
234 destvfs.write('requires', requirements)
235 destvfs.write('sharedpath', sharedpath)
235 destvfs.write('sharedpath', sharedpath)
236
236
237 r = repository(ui, destwvfs.base)
237 r = repository(ui, destwvfs.base)
238 postshare(srcrepo, r, bookmarks=bookmarks)
238 postshare(srcrepo, r, bookmarks=bookmarks)
239
239 _postshareupdate(r, update, checkout=checkout)
240 if update:
241 r.ui.status(_("updating working directory\n"))
242 if update is not True:
243 checkout = update
244 for test in (checkout, 'default', 'tip'):
245 if test is None:
246 continue
247 try:
248 uprev = r.lookup(test)
249 break
250 except error.RepoLookupError:
251 continue
252 _update(r, uprev)
253
240
254 def postshare(sourcerepo, destrepo, bookmarks=True):
241 def postshare(sourcerepo, destrepo, bookmarks=True):
255 """Called after a new shared repo is created.
242 """Called after a new shared repo is created.
256
243
257 The new repo only has a requirements file and pointer to the source.
244 The new repo only has a requirements file and pointer to the source.
258 This function configures additional shared data.
245 This function configures additional shared data.
259
246
260 Extensions can wrap this function and write additional entries to
247 Extensions can wrap this function and write additional entries to
261 destrepo/.hg/shared to indicate additional pieces of data to be shared.
248 destrepo/.hg/shared to indicate additional pieces of data to be shared.
262 """
249 """
263 default = sourcerepo.ui.config('paths', 'default')
250 default = sourcerepo.ui.config('paths', 'default')
264 if default:
251 if default:
265 fp = destrepo.vfs("hgrc", "w", text=True)
252 fp = destrepo.vfs("hgrc", "w", text=True)
266 fp.write("[paths]\n")
253 fp.write("[paths]\n")
267 fp.write("default = %s\n" % default)
254 fp.write("default = %s\n" % default)
268 fp.close()
255 fp.close()
269
256
270 if bookmarks:
257 if bookmarks:
271 fp = destrepo.vfs('shared', 'w')
258 fp = destrepo.vfs('shared', 'w')
272 fp.write('bookmarks\n')
259 fp.write('bookmarks\n')
273 fp.close()
260 fp.close()
274
261
262 def _postshareupdate(repo, update, checkout=None):
263 """Maybe perform a working directory update after a shared repo is created.
264
265 ``update`` can be a boolean or a revision to update to.
266 """
267 if not update:
268 return
269
270 repo.ui.status(_("updating working directory\n"))
271 if update is not True:
272 checkout = update
273 for test in (checkout, 'default', 'tip'):
274 if test is None:
275 continue
276 try:
277 uprev = repo.lookup(test)
278 break
279 except error.RepoLookupError:
280 continue
281 _update(repo, uprev)
282
275 def copystore(ui, srcrepo, destpath):
283 def copystore(ui, srcrepo, destpath):
276 '''copy files from store of srcrepo in destpath
284 '''copy files from store of srcrepo in destpath
277
285
278 returns destlock
286 returns destlock
279 '''
287 '''
280 destlock = None
288 destlock = None
281 try:
289 try:
282 hardlink = None
290 hardlink = None
283 num = 0
291 num = 0
284 closetopic = [None]
292 closetopic = [None]
285 def prog(topic, pos):
293 def prog(topic, pos):
286 if pos is None:
294 if pos is None:
287 closetopic[0] = topic
295 closetopic[0] = topic
288 else:
296 else:
289 ui.progress(topic, pos + num)
297 ui.progress(topic, pos + num)
290 srcpublishing = srcrepo.publishing()
298 srcpublishing = srcrepo.publishing()
291 srcvfs = scmutil.vfs(srcrepo.sharedpath)
299 srcvfs = scmutil.vfs(srcrepo.sharedpath)
292 dstvfs = scmutil.vfs(destpath)
300 dstvfs = scmutil.vfs(destpath)
293 for f in srcrepo.store.copylist():
301 for f in srcrepo.store.copylist():
294 if srcpublishing and f.endswith('phaseroots'):
302 if srcpublishing and f.endswith('phaseroots'):
295 continue
303 continue
296 dstbase = os.path.dirname(f)
304 dstbase = os.path.dirname(f)
297 if dstbase and not dstvfs.exists(dstbase):
305 if dstbase and not dstvfs.exists(dstbase):
298 dstvfs.mkdir(dstbase)
306 dstvfs.mkdir(dstbase)
299 if srcvfs.exists(f):
307 if srcvfs.exists(f):
300 if f.endswith('data'):
308 if f.endswith('data'):
301 # 'dstbase' may be empty (e.g. revlog format 0)
309 # 'dstbase' may be empty (e.g. revlog format 0)
302 lockfile = os.path.join(dstbase, "lock")
310 lockfile = os.path.join(dstbase, "lock")
303 # lock to avoid premature writing to the target
311 # lock to avoid premature writing to the target
304 destlock = lock.lock(dstvfs, lockfile)
312 destlock = lock.lock(dstvfs, lockfile)
305 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
313 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
306 hardlink, progress=prog)
314 hardlink, progress=prog)
307 num += n
315 num += n
308 if hardlink:
316 if hardlink:
309 ui.debug("linked %d files\n" % num)
317 ui.debug("linked %d files\n" % num)
310 if closetopic[0]:
318 if closetopic[0]:
311 ui.progress(closetopic[0], None)
319 ui.progress(closetopic[0], None)
312 else:
320 else:
313 ui.debug("copied %d files\n" % num)
321 ui.debug("copied %d files\n" % num)
314 if closetopic[0]:
322 if closetopic[0]:
315 ui.progress(closetopic[0], None)
323 ui.progress(closetopic[0], None)
316 return destlock
324 return destlock
317 except: # re-raises
325 except: # re-raises
318 release(destlock)
326 release(destlock)
319 raise
327 raise
320
328
321 def clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=False,
329 def clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=False,
322 rev=None, update=True, stream=False):
330 rev=None, update=True, stream=False):
323 """Perform a clone using a shared repo.
331 """Perform a clone using a shared repo.
324
332
325 The store for the repository will be located at <sharepath>/.hg. The
333 The store for the repository will be located at <sharepath>/.hg. The
326 specified revisions will be cloned or pulled from "source". A shared repo
334 specified revisions will be cloned or pulled from "source". A shared repo
327 will be created at "dest" and a working copy will be created if "update" is
335 will be created at "dest" and a working copy will be created if "update" is
328 True.
336 True.
329 """
337 """
330 revs = None
338 revs = None
331 if rev:
339 if rev:
332 if not srcpeer.capable('lookup'):
340 if not srcpeer.capable('lookup'):
333 raise error.Abort(_("src repository does not support "
341 raise error.Abort(_("src repository does not support "
334 "revision lookup and so doesn't "
342 "revision lookup and so doesn't "
335 "support clone by revision"))
343 "support clone by revision"))
336 revs = [srcpeer.lookup(r) for r in rev]
344 revs = [srcpeer.lookup(r) for r in rev]
337
345
338 # Obtain a lock before checking for or cloning the pooled repo otherwise
346 # Obtain a lock before checking for or cloning the pooled repo otherwise
339 # 2 clients may race creating or populating it.
347 # 2 clients may race creating or populating it.
340 pooldir = os.path.dirname(sharepath)
348 pooldir = os.path.dirname(sharepath)
341 # lock class requires the directory to exist.
349 # lock class requires the directory to exist.
342 try:
350 try:
343 util.makedir(pooldir, False)
351 util.makedir(pooldir, False)
344 except OSError as e:
352 except OSError as e:
345 if e.errno != errno.EEXIST:
353 if e.errno != errno.EEXIST:
346 raise
354 raise
347
355
348 poolvfs = scmutil.vfs(pooldir)
356 poolvfs = scmutil.vfs(pooldir)
349 basename = os.path.basename(sharepath)
357 basename = os.path.basename(sharepath)
350
358
351 with lock.lock(poolvfs, '%s.lock' % basename):
359 with lock.lock(poolvfs, '%s.lock' % basename):
352 if os.path.exists(sharepath):
360 if os.path.exists(sharepath):
353 ui.status(_('(sharing from existing pooled repository %s)\n') %
361 ui.status(_('(sharing from existing pooled repository %s)\n') %
354 basename)
362 basename)
355 else:
363 else:
356 ui.status(_('(sharing from new pooled repository %s)\n') % basename)
364 ui.status(_('(sharing from new pooled repository %s)\n') % basename)
357 # Always use pull mode because hardlinks in share mode don't work
365 # Always use pull mode because hardlinks in share mode don't work
358 # well. Never update because working copies aren't necessary in
366 # well. Never update because working copies aren't necessary in
359 # share mode.
367 # share mode.
360 clone(ui, peeropts, source, dest=sharepath, pull=True,
368 clone(ui, peeropts, source, dest=sharepath, pull=True,
361 rev=rev, update=False, stream=stream)
369 rev=rev, update=False, stream=stream)
362
370
363 sharerepo = repository(ui, path=sharepath)
371 sharerepo = repository(ui, path=sharepath)
364 share(ui, sharerepo, dest=dest, update=update, bookmarks=False)
372 share(ui, sharerepo, dest=dest, update=False, bookmarks=False)
365
373
366 # We need to perform a pull against the dest repo to fetch bookmarks
374 # We need to perform a pull against the dest repo to fetch bookmarks
367 # and other non-store data that isn't shared by default. In the case of
375 # and other non-store data that isn't shared by default. In the case of
368 # non-existing shared repo, this means we pull from the remote twice. This
376 # non-existing shared repo, this means we pull from the remote twice. This
369 # is a bit weird. But at the time it was implemented, there wasn't an easy
377 # is a bit weird. But at the time it was implemented, there wasn't an easy
370 # way to pull just non-changegroup data.
378 # way to pull just non-changegroup data.
371 destrepo = repository(ui, path=dest)
379 destrepo = repository(ui, path=dest)
372 exchange.pull(destrepo, srcpeer, heads=revs)
380 exchange.pull(destrepo, srcpeer, heads=revs)
373
381
382 _postshareupdate(destrepo, update)
383
374 return srcpeer, peer(ui, peeropts, dest)
384 return srcpeer, peer(ui, peeropts, dest)
375
385
376 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
386 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
377 update=True, stream=False, branch=None, shareopts=None):
387 update=True, stream=False, branch=None, shareopts=None):
378 """Make a copy of an existing repository.
388 """Make a copy of an existing repository.
379
389
380 Create a copy of an existing repository in a new directory. The
390 Create a copy of an existing repository in a new directory. The
381 source and destination are URLs, as passed to the repository
391 source and destination are URLs, as passed to the repository
382 function. Returns a pair of repository peers, the source and
392 function. Returns a pair of repository peers, the source and
383 newly created destination.
393 newly created destination.
384
394
385 The location of the source is added to the new repository's
395 The location of the source is added to the new repository's
386 .hg/hgrc file, as the default to be used for future pulls and
396 .hg/hgrc file, as the default to be used for future pulls and
387 pushes.
397 pushes.
388
398
389 If an exception is raised, the partly cloned/updated destination
399 If an exception is raised, the partly cloned/updated destination
390 repository will be deleted.
400 repository will be deleted.
391
401
392 Arguments:
402 Arguments:
393
403
394 source: repository object or URL
404 source: repository object or URL
395
405
396 dest: URL of destination repository to create (defaults to base
406 dest: URL of destination repository to create (defaults to base
397 name of source repository)
407 name of source repository)
398
408
399 pull: always pull from source repository, even in local case or if the
409 pull: always pull from source repository, even in local case or if the
400 server prefers streaming
410 server prefers streaming
401
411
402 stream: stream raw data uncompressed from repository (fast over
412 stream: stream raw data uncompressed from repository (fast over
403 LAN, slow over WAN)
413 LAN, slow over WAN)
404
414
405 rev: revision to clone up to (implies pull=True)
415 rev: revision to clone up to (implies pull=True)
406
416
407 update: update working directory after clone completes, if
417 update: update working directory after clone completes, if
408 destination is local repository (True means update to default rev,
418 destination is local repository (True means update to default rev,
409 anything else is treated as a revision)
419 anything else is treated as a revision)
410
420
411 branch: branches to clone
421 branch: branches to clone
412
422
413 shareopts: dict of options to control auto sharing behavior. The "pool" key
423 shareopts: dict of options to control auto sharing behavior. The "pool" key
414 activates auto sharing mode and defines the directory for stores. The
424 activates auto sharing mode and defines the directory for stores. The
415 "mode" key determines how to construct the directory name of the shared
425 "mode" key determines how to construct the directory name of the shared
416 repository. "identity" means the name is derived from the node of the first
426 repository. "identity" means the name is derived from the node of the first
417 changeset in the repository. "remote" means the name is derived from the
427 changeset in the repository. "remote" means the name is derived from the
418 remote's path/URL. Defaults to "identity."
428 remote's path/URL. Defaults to "identity."
419 """
429 """
420
430
421 if isinstance(source, str):
431 if isinstance(source, str):
422 origsource = ui.expandpath(source)
432 origsource = ui.expandpath(source)
423 source, branch = parseurl(origsource, branch)
433 source, branch = parseurl(origsource, branch)
424 srcpeer = peer(ui, peeropts, source)
434 srcpeer = peer(ui, peeropts, source)
425 else:
435 else:
426 srcpeer = source.peer() # in case we were called with a localrepo
436 srcpeer = source.peer() # in case we were called with a localrepo
427 branch = (None, branch or [])
437 branch = (None, branch or [])
428 origsource = source = srcpeer.url()
438 origsource = source = srcpeer.url()
429 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
439 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
430
440
431 if dest is None:
441 if dest is None:
432 dest = defaultdest(source)
442 dest = defaultdest(source)
433 if dest:
443 if dest:
434 ui.status(_("destination directory: %s\n") % dest)
444 ui.status(_("destination directory: %s\n") % dest)
435 else:
445 else:
436 dest = ui.expandpath(dest)
446 dest = ui.expandpath(dest)
437
447
438 dest = util.urllocalpath(dest)
448 dest = util.urllocalpath(dest)
439 source = util.urllocalpath(source)
449 source = util.urllocalpath(source)
440
450
441 if not dest:
451 if not dest:
442 raise error.Abort(_("empty destination path is not valid"))
452 raise error.Abort(_("empty destination path is not valid"))
443
453
444 destvfs = scmutil.vfs(dest, expandpath=True)
454 destvfs = scmutil.vfs(dest, expandpath=True)
445 if destvfs.lexists():
455 if destvfs.lexists():
446 if not destvfs.isdir():
456 if not destvfs.isdir():
447 raise error.Abort(_("destination '%s' already exists") % dest)
457 raise error.Abort(_("destination '%s' already exists") % dest)
448 elif destvfs.listdir():
458 elif destvfs.listdir():
449 raise error.Abort(_("destination '%s' is not empty") % dest)
459 raise error.Abort(_("destination '%s' is not empty") % dest)
450
460
451 shareopts = shareopts or {}
461 shareopts = shareopts or {}
452 sharepool = shareopts.get('pool')
462 sharepool = shareopts.get('pool')
453 sharenamemode = shareopts.get('mode')
463 sharenamemode = shareopts.get('mode')
454 if sharepool and islocal(dest):
464 if sharepool and islocal(dest):
455 sharepath = None
465 sharepath = None
456 if sharenamemode == 'identity':
466 if sharenamemode == 'identity':
457 # Resolve the name from the initial changeset in the remote
467 # Resolve the name from the initial changeset in the remote
458 # repository. This returns nullid when the remote is empty. It
468 # repository. This returns nullid when the remote is empty. It
459 # raises RepoLookupError if revision 0 is filtered or otherwise
469 # raises RepoLookupError if revision 0 is filtered or otherwise
460 # not available. If we fail to resolve, sharing is not enabled.
470 # not available. If we fail to resolve, sharing is not enabled.
461 try:
471 try:
462 rootnode = srcpeer.lookup('0')
472 rootnode = srcpeer.lookup('0')
463 if rootnode != node.nullid:
473 if rootnode != node.nullid:
464 sharepath = os.path.join(sharepool, node.hex(rootnode))
474 sharepath = os.path.join(sharepool, node.hex(rootnode))
465 else:
475 else:
466 ui.status(_('(not using pooled storage: '
476 ui.status(_('(not using pooled storage: '
467 'remote appears to be empty)\n'))
477 'remote appears to be empty)\n'))
468 except error.RepoLookupError:
478 except error.RepoLookupError:
469 ui.status(_('(not using pooled storage: '
479 ui.status(_('(not using pooled storage: '
470 'unable to resolve identity of remote)\n'))
480 'unable to resolve identity of remote)\n'))
471 elif sharenamemode == 'remote':
481 elif sharenamemode == 'remote':
472 sharepath = os.path.join(sharepool, util.sha1(source).hexdigest())
482 sharepath = os.path.join(sharepool, util.sha1(source).hexdigest())
473 else:
483 else:
474 raise error.Abort('unknown share naming mode: %s' % sharenamemode)
484 raise error.Abort('unknown share naming mode: %s' % sharenamemode)
475
485
476 if sharepath:
486 if sharepath:
477 return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
487 return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
478 dest, pull=pull, rev=rev, update=update,
488 dest, pull=pull, rev=rev, update=update,
479 stream=stream)
489 stream=stream)
480
490
481 srclock = destlock = cleandir = None
491 srclock = destlock = cleandir = None
482 srcrepo = srcpeer.local()
492 srcrepo = srcpeer.local()
483 try:
493 try:
484 abspath = origsource
494 abspath = origsource
485 if islocal(origsource):
495 if islocal(origsource):
486 abspath = os.path.abspath(util.urllocalpath(origsource))
496 abspath = os.path.abspath(util.urllocalpath(origsource))
487
497
488 if islocal(dest):
498 if islocal(dest):
489 cleandir = dest
499 cleandir = dest
490
500
491 copy = False
501 copy = False
492 if (srcrepo and srcrepo.cancopy() and islocal(dest)
502 if (srcrepo and srcrepo.cancopy() and islocal(dest)
493 and not phases.hassecret(srcrepo)):
503 and not phases.hassecret(srcrepo)):
494 copy = not pull and not rev
504 copy = not pull and not rev
495
505
496 if copy:
506 if copy:
497 try:
507 try:
498 # we use a lock here because if we race with commit, we
508 # we use a lock here because if we race with commit, we
499 # can end up with extra data in the cloned revlogs that's
509 # can end up with extra data in the cloned revlogs that's
500 # not pointed to by changesets, thus causing verify to
510 # not pointed to by changesets, thus causing verify to
501 # fail
511 # fail
502 srclock = srcrepo.lock(wait=False)
512 srclock = srcrepo.lock(wait=False)
503 except error.LockError:
513 except error.LockError:
504 copy = False
514 copy = False
505
515
506 if copy:
516 if copy:
507 srcrepo.hook('preoutgoing', throw=True, source='clone')
517 srcrepo.hook('preoutgoing', throw=True, source='clone')
508 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
518 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
509 if not os.path.exists(dest):
519 if not os.path.exists(dest):
510 os.mkdir(dest)
520 os.mkdir(dest)
511 else:
521 else:
512 # only clean up directories we create ourselves
522 # only clean up directories we create ourselves
513 cleandir = hgdir
523 cleandir = hgdir
514 try:
524 try:
515 destpath = hgdir
525 destpath = hgdir
516 util.makedir(destpath, notindexed=True)
526 util.makedir(destpath, notindexed=True)
517 except OSError as inst:
527 except OSError as inst:
518 if inst.errno == errno.EEXIST:
528 if inst.errno == errno.EEXIST:
519 cleandir = None
529 cleandir = None
520 raise error.Abort(_("destination '%s' already exists")
530 raise error.Abort(_("destination '%s' already exists")
521 % dest)
531 % dest)
522 raise
532 raise
523
533
524 destlock = copystore(ui, srcrepo, destpath)
534 destlock = copystore(ui, srcrepo, destpath)
525 # copy bookmarks over
535 # copy bookmarks over
526 srcbookmarks = srcrepo.join('bookmarks')
536 srcbookmarks = srcrepo.join('bookmarks')
527 dstbookmarks = os.path.join(destpath, 'bookmarks')
537 dstbookmarks = os.path.join(destpath, 'bookmarks')
528 if os.path.exists(srcbookmarks):
538 if os.path.exists(srcbookmarks):
529 util.copyfile(srcbookmarks, dstbookmarks)
539 util.copyfile(srcbookmarks, dstbookmarks)
530
540
531 # Recomputing branch cache might be slow on big repos,
541 # Recomputing branch cache might be slow on big repos,
532 # so just copy it
542 # so just copy it
533 def copybranchcache(fname):
543 def copybranchcache(fname):
534 srcbranchcache = srcrepo.join('cache/%s' % fname)
544 srcbranchcache = srcrepo.join('cache/%s' % fname)
535 dstbranchcache = os.path.join(dstcachedir, fname)
545 dstbranchcache = os.path.join(dstcachedir, fname)
536 if os.path.exists(srcbranchcache):
546 if os.path.exists(srcbranchcache):
537 if not os.path.exists(dstcachedir):
547 if not os.path.exists(dstcachedir):
538 os.mkdir(dstcachedir)
548 os.mkdir(dstcachedir)
539 util.copyfile(srcbranchcache, dstbranchcache)
549 util.copyfile(srcbranchcache, dstbranchcache)
540
550
541 dstcachedir = os.path.join(destpath, 'cache')
551 dstcachedir = os.path.join(destpath, 'cache')
542 # In local clones we're copying all nodes, not just served
552 # In local clones we're copying all nodes, not just served
543 # ones. Therefore copy all branch caches over.
553 # ones. Therefore copy all branch caches over.
544 copybranchcache('branch2')
554 copybranchcache('branch2')
545 for cachename in repoview.filtertable:
555 for cachename in repoview.filtertable:
546 copybranchcache('branch2-%s' % cachename)
556 copybranchcache('branch2-%s' % cachename)
547
557
548 # we need to re-init the repo after manually copying the data
558 # we need to re-init the repo after manually copying the data
549 # into it
559 # into it
550 destpeer = peer(srcrepo, peeropts, dest)
560 destpeer = peer(srcrepo, peeropts, dest)
551 srcrepo.hook('outgoing', source='clone',
561 srcrepo.hook('outgoing', source='clone',
552 node=node.hex(node.nullid))
562 node=node.hex(node.nullid))
553 else:
563 else:
554 try:
564 try:
555 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
565 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
556 # only pass ui when no srcrepo
566 # only pass ui when no srcrepo
557 except OSError as inst:
567 except OSError as inst:
558 if inst.errno == errno.EEXIST:
568 if inst.errno == errno.EEXIST:
559 cleandir = None
569 cleandir = None
560 raise error.Abort(_("destination '%s' already exists")
570 raise error.Abort(_("destination '%s' already exists")
561 % dest)
571 % dest)
562 raise
572 raise
563
573
564 revs = None
574 revs = None
565 if rev:
575 if rev:
566 if not srcpeer.capable('lookup'):
576 if not srcpeer.capable('lookup'):
567 raise error.Abort(_("src repository does not support "
577 raise error.Abort(_("src repository does not support "
568 "revision lookup and so doesn't "
578 "revision lookup and so doesn't "
569 "support clone by revision"))
579 "support clone by revision"))
570 revs = [srcpeer.lookup(r) for r in rev]
580 revs = [srcpeer.lookup(r) for r in rev]
571 checkout = revs[0]
581 checkout = revs[0]
572 local = destpeer.local()
582 local = destpeer.local()
573 if local:
583 if local:
574 if not stream:
584 if not stream:
575 if pull:
585 if pull:
576 stream = False
586 stream = False
577 else:
587 else:
578 stream = None
588 stream = None
579 # internal config: ui.quietbookmarkmove
589 # internal config: ui.quietbookmarkmove
580 quiet = local.ui.backupconfig('ui', 'quietbookmarkmove')
590 quiet = local.ui.backupconfig('ui', 'quietbookmarkmove')
581 try:
591 try:
582 local.ui.setconfig(
592 local.ui.setconfig(
583 'ui', 'quietbookmarkmove', True, 'clone')
593 'ui', 'quietbookmarkmove', True, 'clone')
584 exchange.pull(local, srcpeer, revs,
594 exchange.pull(local, srcpeer, revs,
585 streamclonerequested=stream)
595 streamclonerequested=stream)
586 finally:
596 finally:
587 local.ui.restoreconfig(quiet)
597 local.ui.restoreconfig(quiet)
588 elif srcrepo:
598 elif srcrepo:
589 exchange.push(srcrepo, destpeer, revs=revs,
599 exchange.push(srcrepo, destpeer, revs=revs,
590 bookmarks=srcrepo._bookmarks.keys())
600 bookmarks=srcrepo._bookmarks.keys())
591 else:
601 else:
592 raise error.Abort(_("clone from remote to remote not supported")
602 raise error.Abort(_("clone from remote to remote not supported")
593 )
603 )
594
604
595 cleandir = None
605 cleandir = None
596
606
597 destrepo = destpeer.local()
607 destrepo = destpeer.local()
598 if destrepo:
608 if destrepo:
599 template = uimod.samplehgrcs['cloned']
609 template = uimod.samplehgrcs['cloned']
600 fp = destrepo.vfs("hgrc", "w", text=True)
610 fp = destrepo.vfs("hgrc", "w", text=True)
601 u = util.url(abspath)
611 u = util.url(abspath)
602 u.passwd = None
612 u.passwd = None
603 defaulturl = str(u)
613 defaulturl = str(u)
604 fp.write(template % defaulturl)
614 fp.write(template % defaulturl)
605 fp.close()
615 fp.close()
606
616
607 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
617 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
608
618
609 if update:
619 if update:
610 if update is not True:
620 if update is not True:
611 checkout = srcpeer.lookup(update)
621 checkout = srcpeer.lookup(update)
612 uprev = None
622 uprev = None
613 status = None
623 status = None
614 if checkout is not None:
624 if checkout is not None:
615 try:
625 try:
616 uprev = destrepo.lookup(checkout)
626 uprev = destrepo.lookup(checkout)
617 except error.RepoLookupError:
627 except error.RepoLookupError:
618 if update is not True:
628 if update is not True:
619 try:
629 try:
620 uprev = destrepo.lookup(update)
630 uprev = destrepo.lookup(update)
621 except error.RepoLookupError:
631 except error.RepoLookupError:
622 pass
632 pass
623 if uprev is None:
633 if uprev is None:
624 try:
634 try:
625 uprev = destrepo._bookmarks['@']
635 uprev = destrepo._bookmarks['@']
626 update = '@'
636 update = '@'
627 bn = destrepo[uprev].branch()
637 bn = destrepo[uprev].branch()
628 if bn == 'default':
638 if bn == 'default':
629 status = _("updating to bookmark @\n")
639 status = _("updating to bookmark @\n")
630 else:
640 else:
631 status = (_("updating to bookmark @ on branch %s\n")
641 status = (_("updating to bookmark @ on branch %s\n")
632 % bn)
642 % bn)
633 except KeyError:
643 except KeyError:
634 try:
644 try:
635 uprev = destrepo.branchtip('default')
645 uprev = destrepo.branchtip('default')
636 except error.RepoLookupError:
646 except error.RepoLookupError:
637 uprev = destrepo.lookup('tip')
647 uprev = destrepo.lookup('tip')
638 if not status:
648 if not status:
639 bn = destrepo[uprev].branch()
649 bn = destrepo[uprev].branch()
640 status = _("updating to branch %s\n") % bn
650 status = _("updating to branch %s\n") % bn
641 destrepo.ui.status(status)
651 destrepo.ui.status(status)
642 _update(destrepo, uprev)
652 _update(destrepo, uprev)
643 if update in destrepo._bookmarks:
653 if update in destrepo._bookmarks:
644 bookmarks.activate(destrepo, update)
654 bookmarks.activate(destrepo, update)
645 finally:
655 finally:
646 release(srclock, destlock)
656 release(srclock, destlock)
647 if cleandir is not None:
657 if cleandir is not None:
648 shutil.rmtree(cleandir, True)
658 shutil.rmtree(cleandir, True)
649 if srcpeer is not None:
659 if srcpeer is not None:
650 srcpeer.close()
660 srcpeer.close()
651 return srcpeer, destpeer
661 return srcpeer, destpeer
652
662
653 def _showstats(repo, stats, quietempty=False):
663 def _showstats(repo, stats, quietempty=False):
654 if quietempty and not any(stats):
664 if quietempty and not any(stats):
655 return
665 return
656 repo.ui.status(_("%d files updated, %d files merged, "
666 repo.ui.status(_("%d files updated, %d files merged, "
657 "%d files removed, %d files unresolved\n") % stats)
667 "%d files removed, %d files unresolved\n") % stats)
658
668
659 def updaterepo(repo, node, overwrite):
669 def updaterepo(repo, node, overwrite):
660 """Update the working directory to node.
670 """Update the working directory to node.
661
671
662 When overwrite is set, changes are clobbered, merged else
672 When overwrite is set, changes are clobbered, merged else
663
673
664 returns stats (see pydoc mercurial.merge.applyupdates)"""
674 returns stats (see pydoc mercurial.merge.applyupdates)"""
665 return mergemod.update(repo, node, False, overwrite,
675 return mergemod.update(repo, node, False, overwrite,
666 labels=['working copy', 'destination'])
676 labels=['working copy', 'destination'])
667
677
668 def update(repo, node, quietempty=False):
678 def update(repo, node, quietempty=False):
669 """update the working directory to node, merging linear changes"""
679 """update the working directory to node, merging linear changes"""
670 stats = updaterepo(repo, node, False)
680 stats = updaterepo(repo, node, False)
671 _showstats(repo, stats, quietempty)
681 _showstats(repo, stats, quietempty)
672 if stats[3]:
682 if stats[3]:
673 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
683 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
674 return stats[3] > 0
684 return stats[3] > 0
675
685
676 # naming conflict in clone()
686 # naming conflict in clone()
677 _update = update
687 _update = update
678
688
679 def clean(repo, node, show_stats=True, quietempty=False):
689 def clean(repo, node, show_stats=True, quietempty=False):
680 """forcibly switch the working directory to node, clobbering changes"""
690 """forcibly switch the working directory to node, clobbering changes"""
681 stats = updaterepo(repo, node, True)
691 stats = updaterepo(repo, node, True)
682 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
692 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
683 if show_stats:
693 if show_stats:
684 _showstats(repo, stats, quietempty)
694 _showstats(repo, stats, quietempty)
685 return stats[3] > 0
695 return stats[3] > 0
686
696
687 def merge(repo, node, force=None, remind=True):
697 def merge(repo, node, force=None, remind=True):
688 """Branch merge with node, resolving changes. Return true if any
698 """Branch merge with node, resolving changes. Return true if any
689 unresolved conflicts."""
699 unresolved conflicts."""
690 stats = mergemod.update(repo, node, True, force)
700 stats = mergemod.update(repo, node, True, force)
691 _showstats(repo, stats)
701 _showstats(repo, stats)
692 if stats[3]:
702 if stats[3]:
693 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
703 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
694 "or 'hg update -C .' to abandon\n"))
704 "or 'hg update -C .' to abandon\n"))
695 elif remind:
705 elif remind:
696 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
706 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
697 return stats[3] > 0
707 return stats[3] > 0
698
708
699 def _incoming(displaychlist, subreporecurse, ui, repo, source,
709 def _incoming(displaychlist, subreporecurse, ui, repo, source,
700 opts, buffered=False):
710 opts, buffered=False):
701 """
711 """
702 Helper for incoming / gincoming.
712 Helper for incoming / gincoming.
703 displaychlist gets called with
713 displaychlist gets called with
704 (remoterepo, incomingchangesetlist, displayer) parameters,
714 (remoterepo, incomingchangesetlist, displayer) parameters,
705 and is supposed to contain only code that can't be unified.
715 and is supposed to contain only code that can't be unified.
706 """
716 """
707 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
717 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
708 other = peer(repo, opts, source)
718 other = peer(repo, opts, source)
709 ui.status(_('comparing with %s\n') % util.hidepassword(source))
719 ui.status(_('comparing with %s\n') % util.hidepassword(source))
710 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
720 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
711
721
712 if revs:
722 if revs:
713 revs = [other.lookup(rev) for rev in revs]
723 revs = [other.lookup(rev) for rev in revs]
714 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
724 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
715 revs, opts["bundle"], opts["force"])
725 revs, opts["bundle"], opts["force"])
716 try:
726 try:
717 if not chlist:
727 if not chlist:
718 ui.status(_("no changes found\n"))
728 ui.status(_("no changes found\n"))
719 return subreporecurse()
729 return subreporecurse()
720
730
721 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
731 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
722 displaychlist(other, chlist, displayer)
732 displaychlist(other, chlist, displayer)
723 displayer.close()
733 displayer.close()
724 finally:
734 finally:
725 cleanupfn()
735 cleanupfn()
726 subreporecurse()
736 subreporecurse()
727 return 0 # exit code is zero since we found incoming changes
737 return 0 # exit code is zero since we found incoming changes
728
738
729 def incoming(ui, repo, source, opts):
739 def incoming(ui, repo, source, opts):
730 def subreporecurse():
740 def subreporecurse():
731 ret = 1
741 ret = 1
732 if opts.get('subrepos'):
742 if opts.get('subrepos'):
733 ctx = repo[None]
743 ctx = repo[None]
734 for subpath in sorted(ctx.substate):
744 for subpath in sorted(ctx.substate):
735 sub = ctx.sub(subpath)
745 sub = ctx.sub(subpath)
736 ret = min(ret, sub.incoming(ui, source, opts))
746 ret = min(ret, sub.incoming(ui, source, opts))
737 return ret
747 return ret
738
748
739 def display(other, chlist, displayer):
749 def display(other, chlist, displayer):
740 limit = cmdutil.loglimit(opts)
750 limit = cmdutil.loglimit(opts)
741 if opts.get('newest_first'):
751 if opts.get('newest_first'):
742 chlist.reverse()
752 chlist.reverse()
743 count = 0
753 count = 0
744 for n in chlist:
754 for n in chlist:
745 if limit is not None and count >= limit:
755 if limit is not None and count >= limit:
746 break
756 break
747 parents = [p for p in other.changelog.parents(n) if p != nullid]
757 parents = [p for p in other.changelog.parents(n) if p != nullid]
748 if opts.get('no_merges') and len(parents) == 2:
758 if opts.get('no_merges') and len(parents) == 2:
749 continue
759 continue
750 count += 1
760 count += 1
751 displayer.show(other[n])
761 displayer.show(other[n])
752 return _incoming(display, subreporecurse, ui, repo, source, opts)
762 return _incoming(display, subreporecurse, ui, repo, source, opts)
753
763
754 def _outgoing(ui, repo, dest, opts):
764 def _outgoing(ui, repo, dest, opts):
755 dest = ui.expandpath(dest or 'default-push', dest or 'default')
765 dest = ui.expandpath(dest or 'default-push', dest or 'default')
756 dest, branches = parseurl(dest, opts.get('branch'))
766 dest, branches = parseurl(dest, opts.get('branch'))
757 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
767 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
758 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
768 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
759 if revs:
769 if revs:
760 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
770 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
761
771
762 other = peer(repo, opts, dest)
772 other = peer(repo, opts, dest)
763 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
773 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
764 force=opts.get('force'))
774 force=opts.get('force'))
765 o = outgoing.missing
775 o = outgoing.missing
766 if not o:
776 if not o:
767 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
777 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
768 return o, other
778 return o, other
769
779
770 def outgoing(ui, repo, dest, opts):
780 def outgoing(ui, repo, dest, opts):
771 def recurse():
781 def recurse():
772 ret = 1
782 ret = 1
773 if opts.get('subrepos'):
783 if opts.get('subrepos'):
774 ctx = repo[None]
784 ctx = repo[None]
775 for subpath in sorted(ctx.substate):
785 for subpath in sorted(ctx.substate):
776 sub = ctx.sub(subpath)
786 sub = ctx.sub(subpath)
777 ret = min(ret, sub.outgoing(ui, dest, opts))
787 ret = min(ret, sub.outgoing(ui, dest, opts))
778 return ret
788 return ret
779
789
780 limit = cmdutil.loglimit(opts)
790 limit = cmdutil.loglimit(opts)
781 o, other = _outgoing(ui, repo, dest, opts)
791 o, other = _outgoing(ui, repo, dest, opts)
782 if not o:
792 if not o:
783 cmdutil.outgoinghooks(ui, repo, other, opts, o)
793 cmdutil.outgoinghooks(ui, repo, other, opts, o)
784 return recurse()
794 return recurse()
785
795
786 if opts.get('newest_first'):
796 if opts.get('newest_first'):
787 o.reverse()
797 o.reverse()
788 displayer = cmdutil.show_changeset(ui, repo, opts)
798 displayer = cmdutil.show_changeset(ui, repo, opts)
789 count = 0
799 count = 0
790 for n in o:
800 for n in o:
791 if limit is not None and count >= limit:
801 if limit is not None and count >= limit:
792 break
802 break
793 parents = [p for p in repo.changelog.parents(n) if p != nullid]
803 parents = [p for p in repo.changelog.parents(n) if p != nullid]
794 if opts.get('no_merges') and len(parents) == 2:
804 if opts.get('no_merges') and len(parents) == 2:
795 continue
805 continue
796 count += 1
806 count += 1
797 displayer.show(repo[n])
807 displayer.show(repo[n])
798 displayer.close()
808 displayer.close()
799 cmdutil.outgoinghooks(ui, repo, other, opts, o)
809 cmdutil.outgoinghooks(ui, repo, other, opts, o)
800 recurse()
810 recurse()
801 return 0 # exit code is zero since we found outgoing changes
811 return 0 # exit code is zero since we found outgoing changes
802
812
803 def verify(repo):
813 def verify(repo):
804 """verify the consistency of a repository"""
814 """verify the consistency of a repository"""
805 ret = verifymod.verify(repo)
815 ret = verifymod.verify(repo)
806
816
807 # Broken subrepo references in hidden csets don't seem worth worrying about,
817 # Broken subrepo references in hidden csets don't seem worth worrying about,
808 # since they can't be pushed/pulled, and --hidden can be used if they are a
818 # since they can't be pushed/pulled, and --hidden can be used if they are a
809 # concern.
819 # concern.
810
820
811 # pathto() is needed for -R case
821 # pathto() is needed for -R case
812 revs = repo.revs("filelog(%s)",
822 revs = repo.revs("filelog(%s)",
813 util.pathto(repo.root, repo.getcwd(), '.hgsubstate'))
823 util.pathto(repo.root, repo.getcwd(), '.hgsubstate'))
814
824
815 if revs:
825 if revs:
816 repo.ui.status(_('checking subrepo links\n'))
826 repo.ui.status(_('checking subrepo links\n'))
817 for rev in revs:
827 for rev in revs:
818 ctx = repo[rev]
828 ctx = repo[rev]
819 try:
829 try:
820 for subpath in ctx.substate:
830 for subpath in ctx.substate:
821 ret = ctx.sub(subpath).verify() or ret
831 ret = ctx.sub(subpath).verify() or ret
822 except Exception:
832 except Exception:
823 repo.ui.warn(_('.hgsubstate is corrupt in revision %s\n') %
833 repo.ui.warn(_('.hgsubstate is corrupt in revision %s\n') %
824 node.short(ctx.node()))
834 node.short(ctx.node()))
825
835
826 return ret
836 return ret
827
837
828 def remoteui(src, opts):
838 def remoteui(src, opts):
829 'build a remote ui from ui or repo and opts'
839 'build a remote ui from ui or repo and opts'
830 if util.safehasattr(src, 'baseui'): # looks like a repository
840 if util.safehasattr(src, 'baseui'): # looks like a repository
831 dst = src.baseui.copy() # drop repo-specific config
841 dst = src.baseui.copy() # drop repo-specific config
832 src = src.ui # copy target options from repo
842 src = src.ui # copy target options from repo
833 else: # assume it's a global ui object
843 else: # assume it's a global ui object
834 dst = src.copy() # keep all global options
844 dst = src.copy() # keep all global options
835
845
836 # copy ssh-specific options
846 # copy ssh-specific options
837 for o in 'ssh', 'remotecmd':
847 for o in 'ssh', 'remotecmd':
838 v = opts.get(o) or src.config('ui', o)
848 v = opts.get(o) or src.config('ui', o)
839 if v:
849 if v:
840 dst.setconfig("ui", o, v, 'copied')
850 dst.setconfig("ui", o, v, 'copied')
841
851
842 # copy bundle-specific options
852 # copy bundle-specific options
843 r = src.config('bundle', 'mainreporoot')
853 r = src.config('bundle', 'mainreporoot')
844 if r:
854 if r:
845 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
855 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
846
856
847 # copy selected local settings to the remote ui
857 # copy selected local settings to the remote ui
848 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
858 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
849 for key, val in src.configitems(sect):
859 for key, val in src.configitems(sect):
850 dst.setconfig(sect, key, val, 'copied')
860 dst.setconfig(sect, key, val, 'copied')
851 v = src.config('web', 'cacerts')
861 v = src.config('web', 'cacerts')
852 if v == '!':
862 if v == '!':
853 dst.setconfig('web', 'cacerts', v, 'copied')
863 dst.setconfig('web', 'cacerts', v, 'copied')
854 elif v:
864 elif v:
855 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
865 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
856
866
857 return dst
867 return dst
858
868
859 # Files of interest
869 # Files of interest
860 # Used to check if the repository has changed looking at mtime and size of
870 # Used to check if the repository has changed looking at mtime and size of
861 # these files.
871 # these files.
862 foi = [('spath', '00changelog.i'),
872 foi = [('spath', '00changelog.i'),
863 ('spath', 'phaseroots'), # ! phase can change content at the same size
873 ('spath', 'phaseroots'), # ! phase can change content at the same size
864 ('spath', 'obsstore'),
874 ('spath', 'obsstore'),
865 ('path', 'bookmarks'), # ! bookmark can change content at the same size
875 ('path', 'bookmarks'), # ! bookmark can change content at the same size
866 ]
876 ]
867
877
868 class cachedlocalrepo(object):
878 class cachedlocalrepo(object):
869 """Holds a localrepository that can be cached and reused."""
879 """Holds a localrepository that can be cached and reused."""
870
880
871 def __init__(self, repo):
881 def __init__(self, repo):
872 """Create a new cached repo from an existing repo.
882 """Create a new cached repo from an existing repo.
873
883
874 We assume the passed in repo was recently created. If the
884 We assume the passed in repo was recently created. If the
875 repo has changed between when it was created and when it was
885 repo has changed between when it was created and when it was
876 turned into a cache, it may not refresh properly.
886 turned into a cache, it may not refresh properly.
877 """
887 """
878 assert isinstance(repo, localrepo.localrepository)
888 assert isinstance(repo, localrepo.localrepository)
879 self._repo = repo
889 self._repo = repo
880 self._state, self.mtime = self._repostate()
890 self._state, self.mtime = self._repostate()
881
891
882 def fetch(self):
892 def fetch(self):
883 """Refresh (if necessary) and return a repository.
893 """Refresh (if necessary) and return a repository.
884
894
885 If the cached instance is out of date, it will be recreated
895 If the cached instance is out of date, it will be recreated
886 automatically and returned.
896 automatically and returned.
887
897
888 Returns a tuple of the repo and a boolean indicating whether a new
898 Returns a tuple of the repo and a boolean indicating whether a new
889 repo instance was created.
899 repo instance was created.
890 """
900 """
891 # We compare the mtimes and sizes of some well-known files to
901 # We compare the mtimes and sizes of some well-known files to
892 # determine if the repo changed. This is not precise, as mtimes
902 # determine if the repo changed. This is not precise, as mtimes
893 # are susceptible to clock skew and imprecise filesystems and
903 # are susceptible to clock skew and imprecise filesystems and
894 # file content can change while maintaining the same size.
904 # file content can change while maintaining the same size.
895
905
896 state, mtime = self._repostate()
906 state, mtime = self._repostate()
897 if state == self._state:
907 if state == self._state:
898 return self._repo, False
908 return self._repo, False
899
909
900 self._repo = repository(self._repo.baseui, self._repo.url())
910 self._repo = repository(self._repo.baseui, self._repo.url())
901 self._state = state
911 self._state = state
902 self.mtime = mtime
912 self.mtime = mtime
903
913
904 return self._repo, True
914 return self._repo, True
905
915
906 def _repostate(self):
916 def _repostate(self):
907 state = []
917 state = []
908 maxmtime = -1
918 maxmtime = -1
909 for attr, fname in foi:
919 for attr, fname in foi:
910 prefix = getattr(self._repo, attr)
920 prefix = getattr(self._repo, attr)
911 p = os.path.join(prefix, fname)
921 p = os.path.join(prefix, fname)
912 try:
922 try:
913 st = os.stat(p)
923 st = os.stat(p)
914 except OSError:
924 except OSError:
915 st = os.stat(prefix)
925 st = os.stat(prefix)
916 state.append((st.st_mtime, st.st_size))
926 state.append((st.st_mtime, st.st_size))
917 maxmtime = max(maxmtime, st.st_mtime)
927 maxmtime = max(maxmtime, st.st_mtime)
918
928
919 return tuple(state), maxmtime
929 return tuple(state), maxmtime
920
930
921 def copy(self):
931 def copy(self):
922 """Obtain a copy of this class instance.
932 """Obtain a copy of this class instance.
923
933
924 A new localrepository instance is obtained. The new instance should be
934 A new localrepository instance is obtained. The new instance should be
925 completely independent of the original.
935 completely independent of the original.
926 """
936 """
927 repo = repository(self._repo.baseui, self._repo.origroot)
937 repo = repository(self._repo.baseui, self._repo.origroot)
928 c = cachedlocalrepo(repo)
938 c = cachedlocalrepo(repo)
929 c._state = self._state
939 c._state = self._state
930 c.mtime = self.mtime
940 c.mtime = self.mtime
931 return c
941 return c
@@ -1,1073 +1,1084
1 Prepare repo a:
1 Prepare repo a:
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ hg add a
6 $ hg add a
7 $ hg commit -m test
7 $ hg commit -m test
8 $ echo first line > b
8 $ echo first line > b
9 $ hg add b
9 $ hg add b
10
10
11 Create a non-inlined filelog:
11 Create a non-inlined filelog:
12
12
13 $ $PYTHON -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
13 $ $PYTHON -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 > cat data1 >> b
15 > cat data1 >> b
16 > hg commit -m test
16 > hg commit -m test
17 > done
17 > done
18
18
19 List files in store/data (should show a 'b.d'):
19 List files in store/data (should show a 'b.d'):
20
20
21 $ for i in .hg/store/data/*; do
21 $ for i in .hg/store/data/*; do
22 > echo $i
22 > echo $i
23 > done
23 > done
24 .hg/store/data/a.i
24 .hg/store/data/a.i
25 .hg/store/data/b.d
25 .hg/store/data/b.d
26 .hg/store/data/b.i
26 .hg/store/data/b.i
27
27
28 Trigger branchcache creation:
28 Trigger branchcache creation:
29
29
30 $ hg branches
30 $ hg branches
31 default 10:a7949464abda
31 default 10:a7949464abda
32 $ ls .hg/cache
32 $ ls .hg/cache
33 branch2-served
33 branch2-served
34 rbc-names-v1
34 rbc-names-v1
35 rbc-revs-v1
35 rbc-revs-v1
36
36
37 Default operation:
37 Default operation:
38
38
39 $ hg clone . ../b
39 $ hg clone . ../b
40 updating to branch default
40 updating to branch default
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ cd ../b
42 $ cd ../b
43
43
44 Ensure branchcache got copied over:
44 Ensure branchcache got copied over:
45
45
46 $ ls .hg/cache
46 $ ls .hg/cache
47 branch2-served
47 branch2-served
48
48
49 $ cat a
49 $ cat a
50 a
50 a
51 $ hg verify
51 $ hg verify
52 checking changesets
52 checking changesets
53 checking manifests
53 checking manifests
54 crosschecking files in changesets and manifests
54 crosschecking files in changesets and manifests
55 checking files
55 checking files
56 2 files, 11 changesets, 11 total revisions
56 2 files, 11 changesets, 11 total revisions
57
57
58 Invalid dest '' must abort:
58 Invalid dest '' must abort:
59
59
60 $ hg clone . ''
60 $ hg clone . ''
61 abort: empty destination path is not valid
61 abort: empty destination path is not valid
62 [255]
62 [255]
63
63
64 No update, with debug option:
64 No update, with debug option:
65
65
66 #if hardlink
66 #if hardlink
67 $ hg --debug clone -U . ../c --config progress.debug=true
67 $ hg --debug clone -U . ../c --config progress.debug=true
68 linking: 1
68 linking: 1
69 linking: 2
69 linking: 2
70 linking: 3
70 linking: 3
71 linking: 4
71 linking: 4
72 linking: 5
72 linking: 5
73 linking: 6
73 linking: 6
74 linking: 7
74 linking: 7
75 linking: 8
75 linking: 8
76 linked 8 files
76 linked 8 files
77 #else
77 #else
78 $ hg --debug clone -U . ../c --config progress.debug=true
78 $ hg --debug clone -U . ../c --config progress.debug=true
79 linking: 1
79 linking: 1
80 copying: 2
80 copying: 2
81 copying: 3
81 copying: 3
82 copying: 4
82 copying: 4
83 copying: 5
83 copying: 5
84 copying: 6
84 copying: 6
85 copying: 7
85 copying: 7
86 copying: 8
86 copying: 8
87 copied 8 files
87 copied 8 files
88 #endif
88 #endif
89 $ cd ../c
89 $ cd ../c
90
90
91 Ensure branchcache got copied over:
91 Ensure branchcache got copied over:
92
92
93 $ ls .hg/cache
93 $ ls .hg/cache
94 branch2-served
94 branch2-served
95
95
96 $ cat a 2>/dev/null || echo "a not present"
96 $ cat a 2>/dev/null || echo "a not present"
97 a not present
97 a not present
98 $ hg verify
98 $ hg verify
99 checking changesets
99 checking changesets
100 checking manifests
100 checking manifests
101 crosschecking files in changesets and manifests
101 crosschecking files in changesets and manifests
102 checking files
102 checking files
103 2 files, 11 changesets, 11 total revisions
103 2 files, 11 changesets, 11 total revisions
104
104
105 Default destination:
105 Default destination:
106
106
107 $ mkdir ../d
107 $ mkdir ../d
108 $ cd ../d
108 $ cd ../d
109 $ hg clone ../a
109 $ hg clone ../a
110 destination directory: a
110 destination directory: a
111 updating to branch default
111 updating to branch default
112 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 $ cd a
113 $ cd a
114 $ hg cat a
114 $ hg cat a
115 a
115 a
116 $ cd ../..
116 $ cd ../..
117
117
118 Check that we drop the 'file:' from the path before writing the .hgrc:
118 Check that we drop the 'file:' from the path before writing the .hgrc:
119
119
120 $ hg clone file:a e
120 $ hg clone file:a e
121 updating to branch default
121 updating to branch default
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 $ grep 'file:' e/.hg/hgrc
123 $ grep 'file:' e/.hg/hgrc
124 [1]
124 [1]
125
125
126 Check that path aliases are expanded:
126 Check that path aliases are expanded:
127
127
128 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
128 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
129 $ hg -R f showconfig paths.default
129 $ hg -R f showconfig paths.default
130 $TESTTMP/a#0 (glob)
130 $TESTTMP/a#0 (glob)
131
131
132 Use --pull:
132 Use --pull:
133
133
134 $ hg clone --pull a g
134 $ hg clone --pull a g
135 requesting all changes
135 requesting all changes
136 adding changesets
136 adding changesets
137 adding manifests
137 adding manifests
138 adding file changes
138 adding file changes
139 added 11 changesets with 11 changes to 2 files
139 added 11 changesets with 11 changes to 2 files
140 updating to branch default
140 updating to branch default
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 $ hg -R g verify
142 $ hg -R g verify
143 checking changesets
143 checking changesets
144 checking manifests
144 checking manifests
145 crosschecking files in changesets and manifests
145 crosschecking files in changesets and manifests
146 checking files
146 checking files
147 2 files, 11 changesets, 11 total revisions
147 2 files, 11 changesets, 11 total revisions
148
148
149 Invalid dest '' with --pull must abort (issue2528):
149 Invalid dest '' with --pull must abort (issue2528):
150
150
151 $ hg clone --pull a ''
151 $ hg clone --pull a ''
152 abort: empty destination path is not valid
152 abort: empty destination path is not valid
153 [255]
153 [255]
154
154
155 Clone to '.':
155 Clone to '.':
156
156
157 $ mkdir h
157 $ mkdir h
158 $ cd h
158 $ cd h
159 $ hg clone ../a .
159 $ hg clone ../a .
160 updating to branch default
160 updating to branch default
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 $ cd ..
162 $ cd ..
163
163
164
164
165 *** Tests for option -u ***
165 *** Tests for option -u ***
166
166
167 Adding some more history to repo a:
167 Adding some more history to repo a:
168
168
169 $ cd a
169 $ cd a
170 $ hg tag ref1
170 $ hg tag ref1
171 $ echo the quick brown fox >a
171 $ echo the quick brown fox >a
172 $ hg ci -m "hacked default"
172 $ hg ci -m "hacked default"
173 $ hg up ref1
173 $ hg up ref1
174 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
175 $ hg branch stable
175 $ hg branch stable
176 marked working directory as branch stable
176 marked working directory as branch stable
177 (branches are permanent and global, did you want a bookmark?)
177 (branches are permanent and global, did you want a bookmark?)
178 $ echo some text >a
178 $ echo some text >a
179 $ hg ci -m "starting branch stable"
179 $ hg ci -m "starting branch stable"
180 $ hg tag ref2
180 $ hg tag ref2
181 $ echo some more text >a
181 $ echo some more text >a
182 $ hg ci -m "another change for branch stable"
182 $ hg ci -m "another change for branch stable"
183 $ hg up ref2
183 $ hg up ref2
184 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
184 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
185 $ hg parents
185 $ hg parents
186 changeset: 13:e8ece76546a6
186 changeset: 13:e8ece76546a6
187 branch: stable
187 branch: stable
188 tag: ref2
188 tag: ref2
189 parent: 10:a7949464abda
189 parent: 10:a7949464abda
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: starting branch stable
192 summary: starting branch stable
193
193
194
194
195 Repo a has two heads:
195 Repo a has two heads:
196
196
197 $ hg heads
197 $ hg heads
198 changeset: 15:0aae7cf88f0d
198 changeset: 15:0aae7cf88f0d
199 branch: stable
199 branch: stable
200 tag: tip
200 tag: tip
201 user: test
201 user: test
202 date: Thu Jan 01 00:00:00 1970 +0000
202 date: Thu Jan 01 00:00:00 1970 +0000
203 summary: another change for branch stable
203 summary: another change for branch stable
204
204
205 changeset: 12:f21241060d6a
205 changeset: 12:f21241060d6a
206 user: test
206 user: test
207 date: Thu Jan 01 00:00:00 1970 +0000
207 date: Thu Jan 01 00:00:00 1970 +0000
208 summary: hacked default
208 summary: hacked default
209
209
210
210
211 $ cd ..
211 $ cd ..
212
212
213
213
214 Testing --noupdate with --updaterev (must abort):
214 Testing --noupdate with --updaterev (must abort):
215
215
216 $ hg clone --noupdate --updaterev 1 a ua
216 $ hg clone --noupdate --updaterev 1 a ua
217 abort: cannot specify both --noupdate and --updaterev
217 abort: cannot specify both --noupdate and --updaterev
218 [255]
218 [255]
219
219
220
220
221 Testing clone -u:
221 Testing clone -u:
222
222
223 $ hg clone -u . a ua
223 $ hg clone -u . a ua
224 updating to branch stable
224 updating to branch stable
225 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
226
226
227 Repo ua has both heads:
227 Repo ua has both heads:
228
228
229 $ hg -R ua heads
229 $ hg -R ua heads
230 changeset: 15:0aae7cf88f0d
230 changeset: 15:0aae7cf88f0d
231 branch: stable
231 branch: stable
232 tag: tip
232 tag: tip
233 user: test
233 user: test
234 date: Thu Jan 01 00:00:00 1970 +0000
234 date: Thu Jan 01 00:00:00 1970 +0000
235 summary: another change for branch stable
235 summary: another change for branch stable
236
236
237 changeset: 12:f21241060d6a
237 changeset: 12:f21241060d6a
238 user: test
238 user: test
239 date: Thu Jan 01 00:00:00 1970 +0000
239 date: Thu Jan 01 00:00:00 1970 +0000
240 summary: hacked default
240 summary: hacked default
241
241
242
242
243 Same revision checked out in repo a and ua:
243 Same revision checked out in repo a and ua:
244
244
245 $ hg -R a parents --template "{node|short}\n"
245 $ hg -R a parents --template "{node|short}\n"
246 e8ece76546a6
246 e8ece76546a6
247 $ hg -R ua parents --template "{node|short}\n"
247 $ hg -R ua parents --template "{node|short}\n"
248 e8ece76546a6
248 e8ece76546a6
249
249
250 $ rm -r ua
250 $ rm -r ua
251
251
252
252
253 Testing clone --pull -u:
253 Testing clone --pull -u:
254
254
255 $ hg clone --pull -u . a ua
255 $ hg clone --pull -u . a ua
256 requesting all changes
256 requesting all changes
257 adding changesets
257 adding changesets
258 adding manifests
258 adding manifests
259 adding file changes
259 adding file changes
260 added 16 changesets with 16 changes to 3 files (+1 heads)
260 added 16 changesets with 16 changes to 3 files (+1 heads)
261 updating to branch stable
261 updating to branch stable
262 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
262 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
263
263
264 Repo ua has both heads:
264 Repo ua has both heads:
265
265
266 $ hg -R ua heads
266 $ hg -R ua heads
267 changeset: 15:0aae7cf88f0d
267 changeset: 15:0aae7cf88f0d
268 branch: stable
268 branch: stable
269 tag: tip
269 tag: tip
270 user: test
270 user: test
271 date: Thu Jan 01 00:00:00 1970 +0000
271 date: Thu Jan 01 00:00:00 1970 +0000
272 summary: another change for branch stable
272 summary: another change for branch stable
273
273
274 changeset: 12:f21241060d6a
274 changeset: 12:f21241060d6a
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
276 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: hacked default
277 summary: hacked default
278
278
279
279
280 Same revision checked out in repo a and ua:
280 Same revision checked out in repo a and ua:
281
281
282 $ hg -R a parents --template "{node|short}\n"
282 $ hg -R a parents --template "{node|short}\n"
283 e8ece76546a6
283 e8ece76546a6
284 $ hg -R ua parents --template "{node|short}\n"
284 $ hg -R ua parents --template "{node|short}\n"
285 e8ece76546a6
285 e8ece76546a6
286
286
287 $ rm -r ua
287 $ rm -r ua
288
288
289
289
290 Testing clone -u <branch>:
290 Testing clone -u <branch>:
291
291
292 $ hg clone -u stable a ua
292 $ hg clone -u stable a ua
293 updating to branch stable
293 updating to branch stable
294 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
295
295
296 Repo ua has both heads:
296 Repo ua has both heads:
297
297
298 $ hg -R ua heads
298 $ hg -R ua heads
299 changeset: 15:0aae7cf88f0d
299 changeset: 15:0aae7cf88f0d
300 branch: stable
300 branch: stable
301 tag: tip
301 tag: tip
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
304 summary: another change for branch stable
304 summary: another change for branch stable
305
305
306 changeset: 12:f21241060d6a
306 changeset: 12:f21241060d6a
307 user: test
307 user: test
308 date: Thu Jan 01 00:00:00 1970 +0000
308 date: Thu Jan 01 00:00:00 1970 +0000
309 summary: hacked default
309 summary: hacked default
310
310
311
311
312 Branch 'stable' is checked out:
312 Branch 'stable' is checked out:
313
313
314 $ hg -R ua parents
314 $ hg -R ua parents
315 changeset: 15:0aae7cf88f0d
315 changeset: 15:0aae7cf88f0d
316 branch: stable
316 branch: stable
317 tag: tip
317 tag: tip
318 user: test
318 user: test
319 date: Thu Jan 01 00:00:00 1970 +0000
319 date: Thu Jan 01 00:00:00 1970 +0000
320 summary: another change for branch stable
320 summary: another change for branch stable
321
321
322
322
323 $ rm -r ua
323 $ rm -r ua
324
324
325
325
326 Testing default checkout:
326 Testing default checkout:
327
327
328 $ hg clone a ua
328 $ hg clone a ua
329 updating to branch default
329 updating to branch default
330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
331
331
332 Repo ua has both heads:
332 Repo ua has both heads:
333
333
334 $ hg -R ua heads
334 $ hg -R ua heads
335 changeset: 15:0aae7cf88f0d
335 changeset: 15:0aae7cf88f0d
336 branch: stable
336 branch: stable
337 tag: tip
337 tag: tip
338 user: test
338 user: test
339 date: Thu Jan 01 00:00:00 1970 +0000
339 date: Thu Jan 01 00:00:00 1970 +0000
340 summary: another change for branch stable
340 summary: another change for branch stable
341
341
342 changeset: 12:f21241060d6a
342 changeset: 12:f21241060d6a
343 user: test
343 user: test
344 date: Thu Jan 01 00:00:00 1970 +0000
344 date: Thu Jan 01 00:00:00 1970 +0000
345 summary: hacked default
345 summary: hacked default
346
346
347
347
348 Branch 'default' is checked out:
348 Branch 'default' is checked out:
349
349
350 $ hg -R ua parents
350 $ hg -R ua parents
351 changeset: 12:f21241060d6a
351 changeset: 12:f21241060d6a
352 user: test
352 user: test
353 date: Thu Jan 01 00:00:00 1970 +0000
353 date: Thu Jan 01 00:00:00 1970 +0000
354 summary: hacked default
354 summary: hacked default
355
355
356 Test clone with a branch named "@" (issue3677)
356 Test clone with a branch named "@" (issue3677)
357
357
358 $ hg -R ua branch @
358 $ hg -R ua branch @
359 marked working directory as branch @
359 marked working directory as branch @
360 $ hg -R ua commit -m 'created branch @'
360 $ hg -R ua commit -m 'created branch @'
361 $ hg clone ua atbranch
361 $ hg clone ua atbranch
362 updating to branch default
362 updating to branch default
363 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 $ hg -R atbranch heads
364 $ hg -R atbranch heads
365 changeset: 16:798b6d97153e
365 changeset: 16:798b6d97153e
366 branch: @
366 branch: @
367 tag: tip
367 tag: tip
368 parent: 12:f21241060d6a
368 parent: 12:f21241060d6a
369 user: test
369 user: test
370 date: Thu Jan 01 00:00:00 1970 +0000
370 date: Thu Jan 01 00:00:00 1970 +0000
371 summary: created branch @
371 summary: created branch @
372
372
373 changeset: 15:0aae7cf88f0d
373 changeset: 15:0aae7cf88f0d
374 branch: stable
374 branch: stable
375 user: test
375 user: test
376 date: Thu Jan 01 00:00:00 1970 +0000
376 date: Thu Jan 01 00:00:00 1970 +0000
377 summary: another change for branch stable
377 summary: another change for branch stable
378
378
379 changeset: 12:f21241060d6a
379 changeset: 12:f21241060d6a
380 user: test
380 user: test
381 date: Thu Jan 01 00:00:00 1970 +0000
381 date: Thu Jan 01 00:00:00 1970 +0000
382 summary: hacked default
382 summary: hacked default
383
383
384 $ hg -R atbranch parents
384 $ hg -R atbranch parents
385 changeset: 12:f21241060d6a
385 changeset: 12:f21241060d6a
386 user: test
386 user: test
387 date: Thu Jan 01 00:00:00 1970 +0000
387 date: Thu Jan 01 00:00:00 1970 +0000
388 summary: hacked default
388 summary: hacked default
389
389
390
390
391 $ rm -r ua atbranch
391 $ rm -r ua atbranch
392
392
393
393
394 Testing #<branch>:
394 Testing #<branch>:
395
395
396 $ hg clone -u . a#stable ua
396 $ hg clone -u . a#stable ua
397 adding changesets
397 adding changesets
398 adding manifests
398 adding manifests
399 adding file changes
399 adding file changes
400 added 14 changesets with 14 changes to 3 files
400 added 14 changesets with 14 changes to 3 files
401 updating to branch stable
401 updating to branch stable
402 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
403
403
404 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
404 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
405
405
406 $ hg -R ua heads
406 $ hg -R ua heads
407 changeset: 13:0aae7cf88f0d
407 changeset: 13:0aae7cf88f0d
408 branch: stable
408 branch: stable
409 tag: tip
409 tag: tip
410 user: test
410 user: test
411 date: Thu Jan 01 00:00:00 1970 +0000
411 date: Thu Jan 01 00:00:00 1970 +0000
412 summary: another change for branch stable
412 summary: another change for branch stable
413
413
414 changeset: 10:a7949464abda
414 changeset: 10:a7949464abda
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
417 summary: test
417 summary: test
418
418
419
419
420 Same revision checked out in repo a and ua:
420 Same revision checked out in repo a and ua:
421
421
422 $ hg -R a parents --template "{node|short}\n"
422 $ hg -R a parents --template "{node|short}\n"
423 e8ece76546a6
423 e8ece76546a6
424 $ hg -R ua parents --template "{node|short}\n"
424 $ hg -R ua parents --template "{node|short}\n"
425 e8ece76546a6
425 e8ece76546a6
426
426
427 $ rm -r ua
427 $ rm -r ua
428
428
429
429
430 Testing -u -r <branch>:
430 Testing -u -r <branch>:
431
431
432 $ hg clone -u . -r stable a ua
432 $ hg clone -u . -r stable a ua
433 adding changesets
433 adding changesets
434 adding manifests
434 adding manifests
435 adding file changes
435 adding file changes
436 added 14 changesets with 14 changes to 3 files
436 added 14 changesets with 14 changes to 3 files
437 updating to branch stable
437 updating to branch stable
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
439
439
440 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
440 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
441
441
442 $ hg -R ua heads
442 $ hg -R ua heads
443 changeset: 13:0aae7cf88f0d
443 changeset: 13:0aae7cf88f0d
444 branch: stable
444 branch: stable
445 tag: tip
445 tag: tip
446 user: test
446 user: test
447 date: Thu Jan 01 00:00:00 1970 +0000
447 date: Thu Jan 01 00:00:00 1970 +0000
448 summary: another change for branch stable
448 summary: another change for branch stable
449
449
450 changeset: 10:a7949464abda
450 changeset: 10:a7949464abda
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: test
453 summary: test
454
454
455
455
456 Same revision checked out in repo a and ua:
456 Same revision checked out in repo a and ua:
457
457
458 $ hg -R a parents --template "{node|short}\n"
458 $ hg -R a parents --template "{node|short}\n"
459 e8ece76546a6
459 e8ece76546a6
460 $ hg -R ua parents --template "{node|short}\n"
460 $ hg -R ua parents --template "{node|short}\n"
461 e8ece76546a6
461 e8ece76546a6
462
462
463 $ rm -r ua
463 $ rm -r ua
464
464
465
465
466 Testing -r <branch>:
466 Testing -r <branch>:
467
467
468 $ hg clone -r stable a ua
468 $ hg clone -r stable a ua
469 adding changesets
469 adding changesets
470 adding manifests
470 adding manifests
471 adding file changes
471 adding file changes
472 added 14 changesets with 14 changes to 3 files
472 added 14 changesets with 14 changes to 3 files
473 updating to branch stable
473 updating to branch stable
474 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
474 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
475
475
476 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
476 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
477
477
478 $ hg -R ua heads
478 $ hg -R ua heads
479 changeset: 13:0aae7cf88f0d
479 changeset: 13:0aae7cf88f0d
480 branch: stable
480 branch: stable
481 tag: tip
481 tag: tip
482 user: test
482 user: test
483 date: Thu Jan 01 00:00:00 1970 +0000
483 date: Thu Jan 01 00:00:00 1970 +0000
484 summary: another change for branch stable
484 summary: another change for branch stable
485
485
486 changeset: 10:a7949464abda
486 changeset: 10:a7949464abda
487 user: test
487 user: test
488 date: Thu Jan 01 00:00:00 1970 +0000
488 date: Thu Jan 01 00:00:00 1970 +0000
489 summary: test
489 summary: test
490
490
491
491
492 Branch 'stable' is checked out:
492 Branch 'stable' is checked out:
493
493
494 $ hg -R ua parents
494 $ hg -R ua parents
495 changeset: 13:0aae7cf88f0d
495 changeset: 13:0aae7cf88f0d
496 branch: stable
496 branch: stable
497 tag: tip
497 tag: tip
498 user: test
498 user: test
499 date: Thu Jan 01 00:00:00 1970 +0000
499 date: Thu Jan 01 00:00:00 1970 +0000
500 summary: another change for branch stable
500 summary: another change for branch stable
501
501
502
502
503 $ rm -r ua
503 $ rm -r ua
504
504
505
505
506 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
506 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
507 iterable in addbranchrevs()
507 iterable in addbranchrevs()
508
508
509 $ cat <<EOF > simpleclone.py
509 $ cat <<EOF > simpleclone.py
510 > from mercurial import ui, hg
510 > from mercurial import ui, hg
511 > myui = ui.ui()
511 > myui = ui.ui()
512 > repo = hg.repository(myui, 'a')
512 > repo = hg.repository(myui, 'a')
513 > hg.clone(myui, {}, repo, dest="ua")
513 > hg.clone(myui, {}, repo, dest="ua")
514 > EOF
514 > EOF
515
515
516 $ python simpleclone.py
516 $ python simpleclone.py
517 updating to branch default
517 updating to branch default
518 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
518 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
519
519
520 $ rm -r ua
520 $ rm -r ua
521
521
522 $ cat <<EOF > branchclone.py
522 $ cat <<EOF > branchclone.py
523 > from mercurial import ui, hg, extensions
523 > from mercurial import ui, hg, extensions
524 > myui = ui.ui()
524 > myui = ui.ui()
525 > extensions.loadall(myui)
525 > extensions.loadall(myui)
526 > repo = hg.repository(myui, 'a')
526 > repo = hg.repository(myui, 'a')
527 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
527 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
528 > EOF
528 > EOF
529
529
530 $ python branchclone.py
530 $ python branchclone.py
531 adding changesets
531 adding changesets
532 adding manifests
532 adding manifests
533 adding file changes
533 adding file changes
534 added 14 changesets with 14 changes to 3 files
534 added 14 changesets with 14 changes to 3 files
535 updating to branch stable
535 updating to branch stable
536 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
536 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
537 $ rm -r ua
537 $ rm -r ua
538
538
539
539
540 Test clone with special '@' bookmark:
540 Test clone with special '@' bookmark:
541 $ cd a
541 $ cd a
542 $ hg bookmark -r a7949464abda @ # branch point of stable from default
542 $ hg bookmark -r a7949464abda @ # branch point of stable from default
543 $ hg clone . ../i
543 $ hg clone . ../i
544 updating to bookmark @
544 updating to bookmark @
545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
546 $ hg id -i ../i
546 $ hg id -i ../i
547 a7949464abda
547 a7949464abda
548 $ rm -r ../i
548 $ rm -r ../i
549
549
550 $ hg bookmark -f -r stable @
550 $ hg bookmark -f -r stable @
551 $ hg bookmarks
551 $ hg bookmarks
552 @ 15:0aae7cf88f0d
552 @ 15:0aae7cf88f0d
553 $ hg clone . ../i
553 $ hg clone . ../i
554 updating to bookmark @ on branch stable
554 updating to bookmark @ on branch stable
555 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
555 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 $ hg id -i ../i
556 $ hg id -i ../i
557 0aae7cf88f0d
557 0aae7cf88f0d
558 $ cd "$TESTTMP"
558 $ cd "$TESTTMP"
559
559
560
560
561 Testing failures:
561 Testing failures:
562
562
563 $ mkdir fail
563 $ mkdir fail
564 $ cd fail
564 $ cd fail
565
565
566 No local source
566 No local source
567
567
568 $ hg clone a b
568 $ hg clone a b
569 abort: repository a not found!
569 abort: repository a not found!
570 [255]
570 [255]
571
571
572 No remote source
572 No remote source
573
573
574 #if windows
574 #if windows
575 $ hg clone http://127.0.0.1:3121/a b
575 $ hg clone http://127.0.0.1:3121/a b
576 abort: error: * (glob)
576 abort: error: * (glob)
577 [255]
577 [255]
578 #else
578 #else
579 $ hg clone http://127.0.0.1:3121/a b
579 $ hg clone http://127.0.0.1:3121/a b
580 abort: error: *refused* (glob)
580 abort: error: *refused* (glob)
581 [255]
581 [255]
582 #endif
582 #endif
583 $ rm -rf b # work around bug with http clone
583 $ rm -rf b # work around bug with http clone
584
584
585
585
586 #if unix-permissions no-root
586 #if unix-permissions no-root
587
587
588 Inaccessible source
588 Inaccessible source
589
589
590 $ mkdir a
590 $ mkdir a
591 $ chmod 000 a
591 $ chmod 000 a
592 $ hg clone a b
592 $ hg clone a b
593 abort: repository a not found!
593 abort: repository a not found!
594 [255]
594 [255]
595
595
596 Inaccessible destination
596 Inaccessible destination
597
597
598 $ hg init b
598 $ hg init b
599 $ cd b
599 $ cd b
600 $ hg clone . ../a
600 $ hg clone . ../a
601 abort: Permission denied: '../a'
601 abort: Permission denied: '../a'
602 [255]
602 [255]
603 $ cd ..
603 $ cd ..
604 $ chmod 700 a
604 $ chmod 700 a
605 $ rm -r a b
605 $ rm -r a b
606
606
607 #endif
607 #endif
608
608
609
609
610 #if fifo
610 #if fifo
611
611
612 Source of wrong type
612 Source of wrong type
613
613
614 $ mkfifo a
614 $ mkfifo a
615 $ hg clone a b
615 $ hg clone a b
616 abort: repository a not found!
616 abort: repository a not found!
617 [255]
617 [255]
618 $ rm a
618 $ rm a
619
619
620 #endif
620 #endif
621
621
622 Default destination, same directory
622 Default destination, same directory
623
623
624 $ hg init q
624 $ hg init q
625 $ hg clone q
625 $ hg clone q
626 destination directory: q
626 destination directory: q
627 abort: destination 'q' is not empty
627 abort: destination 'q' is not empty
628 [255]
628 [255]
629
629
630 destination directory not empty
630 destination directory not empty
631
631
632 $ mkdir a
632 $ mkdir a
633 $ echo stuff > a/a
633 $ echo stuff > a/a
634 $ hg clone q a
634 $ hg clone q a
635 abort: destination 'a' is not empty
635 abort: destination 'a' is not empty
636 [255]
636 [255]
637
637
638
638
639 #if unix-permissions no-root
639 #if unix-permissions no-root
640
640
641 leave existing directory in place after clone failure
641 leave existing directory in place after clone failure
642
642
643 $ hg init c
643 $ hg init c
644 $ cd c
644 $ cd c
645 $ echo c > c
645 $ echo c > c
646 $ hg commit -A -m test
646 $ hg commit -A -m test
647 adding c
647 adding c
648 $ chmod -rx .hg/store/data
648 $ chmod -rx .hg/store/data
649 $ cd ..
649 $ cd ..
650 $ mkdir d
650 $ mkdir d
651 $ hg clone c d 2> err
651 $ hg clone c d 2> err
652 [255]
652 [255]
653 $ test -d d
653 $ test -d d
654 $ test -d d/.hg
654 $ test -d d/.hg
655 [1]
655 [1]
656
656
657 re-enable perm to allow deletion
657 re-enable perm to allow deletion
658
658
659 $ chmod +rx c/.hg/store/data
659 $ chmod +rx c/.hg/store/data
660
660
661 #endif
661 #endif
662
662
663 $ cd ..
663 $ cd ..
664
664
665 Test clone from the repository in (emulated) revlog format 0 (issue4203):
665 Test clone from the repository in (emulated) revlog format 0 (issue4203):
666
666
667 $ mkdir issue4203
667 $ mkdir issue4203
668 $ mkdir -p src/.hg
668 $ mkdir -p src/.hg
669 $ echo foo > src/foo
669 $ echo foo > src/foo
670 $ hg -R src add src/foo
670 $ hg -R src add src/foo
671 $ hg -R src commit -m '#0'
671 $ hg -R src commit -m '#0'
672 $ hg -R src log -q
672 $ hg -R src log -q
673 0:e1bab28bca43
673 0:e1bab28bca43
674 $ hg clone -U -q src dst
674 $ hg clone -U -q src dst
675 $ hg -R dst log -q
675 $ hg -R dst log -q
676 0:e1bab28bca43
676 0:e1bab28bca43
677
677
678 Create repositories to test auto sharing functionality
678 Create repositories to test auto sharing functionality
679
679
680 $ cat >> $HGRCPATH << EOF
680 $ cat >> $HGRCPATH << EOF
681 > [extensions]
681 > [extensions]
682 > share=
682 > share=
683 > EOF
683 > EOF
684
684
685 $ hg init empty
685 $ hg init empty
686 $ hg init source1a
686 $ hg init source1a
687 $ cd source1a
687 $ cd source1a
688 $ echo initial1 > foo
688 $ echo initial1 > foo
689 $ hg -q commit -A -m initial
689 $ hg -q commit -A -m initial
690 $ echo second > foo
690 $ echo second > foo
691 $ hg commit -m second
691 $ hg commit -m second
692 $ cd ..
692 $ cd ..
693
693
694 $ hg init filteredrev0
694 $ hg init filteredrev0
695 $ cd filteredrev0
695 $ cd filteredrev0
696 $ cat >> .hg/hgrc << EOF
696 $ cat >> .hg/hgrc << EOF
697 > [experimental]
697 > [experimental]
698 > evolution=createmarkers
698 > evolution=createmarkers
699 > EOF
699 > EOF
700 $ echo initial1 > foo
700 $ echo initial1 > foo
701 $ hg -q commit -A -m initial0
701 $ hg -q commit -A -m initial0
702 $ hg -q up -r null
702 $ hg -q up -r null
703 $ echo initial2 > foo
703 $ echo initial2 > foo
704 $ hg -q commit -A -m initial1
704 $ hg -q commit -A -m initial1
705 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
705 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
706 $ cd ..
706 $ cd ..
707
707
708 $ hg -q clone --pull source1a source1b
708 $ hg -q clone --pull source1a source1b
709 $ cd source1a
709 $ cd source1a
710 $ hg bookmark bookA
710 $ hg bookmark bookA
711 $ echo 1a > foo
711 $ echo 1a > foo
712 $ hg commit -m 1a
712 $ hg commit -m 1a
713 $ cd ../source1b
713 $ cd ../source1b
714 $ hg -q up -r 0
714 $ hg -q up -r 0
715 $ echo head1 > foo
715 $ echo head1 > foo
716 $ hg commit -m head1
716 $ hg commit -m head1
717 created new head
717 created new head
718 $ hg bookmark head1
718 $ hg bookmark head1
719 $ hg -q up -r 0
719 $ hg -q up -r 0
720 $ echo head2 > foo
720 $ echo head2 > foo
721 $ hg commit -m head2
721 $ hg commit -m head2
722 created new head
722 created new head
723 $ hg bookmark head2
723 $ hg bookmark head2
724 $ hg -q up -r 0
724 $ hg -q up -r 0
725 $ hg branch branch1
725 $ hg branch branch1
726 marked working directory as branch branch1
726 marked working directory as branch branch1
727 (branches are permanent and global, did you want a bookmark?)
727 (branches are permanent and global, did you want a bookmark?)
728 $ echo branch1 > foo
728 $ echo branch1 > foo
729 $ hg commit -m branch1
729 $ hg commit -m branch1
730 $ hg -q up -r 0
730 $ hg -q up -r 0
731 $ hg branch branch2
731 $ hg branch branch2
732 marked working directory as branch branch2
732 marked working directory as branch branch2
733 $ echo branch2 > foo
733 $ echo branch2 > foo
734 $ hg commit -m branch2
734 $ hg commit -m branch2
735 $ cd ..
735 $ cd ..
736 $ hg init source2
736 $ hg init source2
737 $ cd source2
737 $ cd source2
738 $ echo initial2 > foo
738 $ echo initial2 > foo
739 $ hg -q commit -A -m initial2
739 $ hg -q commit -A -m initial2
740 $ echo second > foo
740 $ echo second > foo
741 $ hg commit -m second
741 $ hg commit -m second
742 $ cd ..
742 $ cd ..
743
743
744 Clone with auto share from an empty repo should not result in share
744 Clone with auto share from an empty repo should not result in share
745
745
746 $ mkdir share
746 $ mkdir share
747 $ hg --config share.pool=share clone empty share-empty
747 $ hg --config share.pool=share clone empty share-empty
748 (not using pooled storage: remote appears to be empty)
748 (not using pooled storage: remote appears to be empty)
749 updating to branch default
749 updating to branch default
750 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
750 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
751 $ ls share
751 $ ls share
752 $ test -d share-empty/.hg/store
752 $ test -d share-empty/.hg/store
753 $ test -f share-empty/.hg/sharedpath
753 $ test -f share-empty/.hg/sharedpath
754 [1]
754 [1]
755
755
756 Clone with auto share from a repo with filtered revision 0 should not result in share
756 Clone with auto share from a repo with filtered revision 0 should not result in share
757
757
758 $ hg --config share.pool=share clone filteredrev0 share-filtered
758 $ hg --config share.pool=share clone filteredrev0 share-filtered
759 (not using pooled storage: unable to resolve identity of remote)
759 (not using pooled storage: unable to resolve identity of remote)
760 requesting all changes
760 requesting all changes
761 adding changesets
761 adding changesets
762 adding manifests
762 adding manifests
763 adding file changes
763 adding file changes
764 added 1 changesets with 1 changes to 1 files
764 added 1 changesets with 1 changes to 1 files
765 updating to branch default
765 updating to branch default
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
767
768 Clone from repo with content should result in shared store being created
768 Clone from repo with content should result in shared store being created
769
769
770 $ hg --config share.pool=share clone source1a share-dest1a
770 $ hg --config share.pool=share clone source1a share-dest1a
771 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
771 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
772 requesting all changes
772 requesting all changes
773 adding changesets
773 adding changesets
774 adding manifests
774 adding manifests
775 adding file changes
775 adding file changes
776 added 3 changesets with 3 changes to 1 files
776 added 3 changesets with 3 changes to 1 files
777 updating working directory
778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
779 searching for changes
777 searching for changes
780 no changes found
778 no changes found
781 adding remote bookmark bookA
779 adding remote bookmark bookA
780 updating working directory
781 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
782
782
783 The shared repo should have been created
783 The shared repo should have been created
784
784
785 $ ls share
785 $ ls share
786 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
786 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
787
787
788 The destination should point to it
788 The destination should point to it
789
789
790 $ cat share-dest1a/.hg/sharedpath; echo
790 $ cat share-dest1a/.hg/sharedpath; echo
791 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
791 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
792
792
793 The destination should have bookmarks
793 The destination should have bookmarks
794
794
795 $ hg -R share-dest1a bookmarks
795 $ hg -R share-dest1a bookmarks
796 bookA 2:e5bfe23c0b47
796 bookA 2:e5bfe23c0b47
797
797
798 The default path should be the remote, not the share
798 The default path should be the remote, not the share
799
799
800 $ hg -R share-dest1a config paths.default
800 $ hg -R share-dest1a config paths.default
801 $TESTTMP/source1a (glob)
801 $TESTTMP/source1a (glob)
802
802
803 Clone with existing share dir should result in pull + share
803 Clone with existing share dir should result in pull + share
804
804
805 $ hg --config share.pool=share clone source1b share-dest1b
805 $ hg --config share.pool=share clone source1b share-dest1b
806 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
806 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
807 updating working directory
808 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
809 searching for changes
807 searching for changes
810 adding changesets
808 adding changesets
811 adding manifests
809 adding manifests
812 adding file changes
810 adding file changes
813 added 4 changesets with 4 changes to 1 files (+4 heads)
811 added 4 changesets with 4 changes to 1 files (+4 heads)
814 adding remote bookmark head1
812 adding remote bookmark head1
815 adding remote bookmark head2
813 adding remote bookmark head2
814 updating working directory
815 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
816
816
817 $ ls share
817 $ ls share
818 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
818 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
819
819
820 $ cat share-dest1b/.hg/sharedpath; echo
820 $ cat share-dest1b/.hg/sharedpath; echo
821 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
821 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
822
822
823 We only get bookmarks from the remote, not everything in the share
823 We only get bookmarks from the remote, not everything in the share
824
824
825 $ hg -R share-dest1b bookmarks
825 $ hg -R share-dest1b bookmarks
826 head1 3:4a8dc1ab4c13
826 head1 3:4a8dc1ab4c13
827 head2 4:99f71071f117
827 head2 4:99f71071f117
828
828
829 Default path should be source, not share.
829 Default path should be source, not share.
830
830
831 $ hg -R share-dest1b config paths.default
831 $ hg -R share-dest1b config paths.default
832 $TESTTMP/source1a (glob)
832 $TESTTMP/source1a (glob)
833
833
834 Checked out revision should be head of default branch
835
836 $ hg -R share-dest1b log -r .
837 changeset: 4:99f71071f117
838 bookmark: head2
839 parent: 0:b5f04eac9d8f
840 user: test
841 date: Thu Jan 01 00:00:00 1970 +0000
842 summary: head2
843
844
834 Clone from unrelated repo should result in new share
845 Clone from unrelated repo should result in new share
835
846
836 $ hg --config share.pool=share clone source2 share-dest2
847 $ hg --config share.pool=share clone source2 share-dest2
837 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
848 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
838 requesting all changes
849 requesting all changes
839 adding changesets
850 adding changesets
840 adding manifests
851 adding manifests
841 adding file changes
852 adding file changes
842 added 2 changesets with 2 changes to 1 files
853 added 2 changesets with 2 changes to 1 files
854 searching for changes
855 no changes found
843 updating working directory
856 updating working directory
844 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
857 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
845 searching for changes
846 no changes found
847
858
848 $ ls share
859 $ ls share
849 22aeff664783fd44c6d9b435618173c118c3448e
860 22aeff664783fd44c6d9b435618173c118c3448e
850 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
861 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
851
862
852 remote naming mode works as advertised
863 remote naming mode works as advertised
853
864
854 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
865 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
855 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
866 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
856 requesting all changes
867 requesting all changes
857 adding changesets
868 adding changesets
858 adding manifests
869 adding manifests
859 adding file changes
870 adding file changes
860 added 3 changesets with 3 changes to 1 files
871 added 3 changesets with 3 changes to 1 files
861 updating working directory
862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 searching for changes
872 searching for changes
864 no changes found
873 no changes found
865 adding remote bookmark bookA
874 adding remote bookmark bookA
875 updating working directory
876 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
866
877
867 $ ls shareremote
878 $ ls shareremote
868 195bb1fcdb595c14a6c13e0269129ed78f6debde
879 195bb1fcdb595c14a6c13e0269129ed78f6debde
869
880
870 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
881 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
871 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
882 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
872 requesting all changes
883 requesting all changes
873 adding changesets
884 adding changesets
874 adding manifests
885 adding manifests
875 adding file changes
886 adding file changes
876 added 6 changesets with 6 changes to 1 files (+4 heads)
887 added 6 changesets with 6 changes to 1 files (+4 heads)
877 updating working directory
878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 searching for changes
888 searching for changes
880 no changes found
889 no changes found
881 adding remote bookmark head1
890 adding remote bookmark head1
882 adding remote bookmark head2
891 adding remote bookmark head2
892 updating working directory
893 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
883
894
884 $ ls shareremote
895 $ ls shareremote
885 195bb1fcdb595c14a6c13e0269129ed78f6debde
896 195bb1fcdb595c14a6c13e0269129ed78f6debde
886 c0d4f83847ca2a873741feb7048a45085fd47c46
897 c0d4f83847ca2a873741feb7048a45085fd47c46
887
898
888 request to clone a single revision is respected in sharing mode
899 request to clone a single revision is respected in sharing mode
889
900
890 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
901 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
891 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
902 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
892 adding changesets
903 adding changesets
893 adding manifests
904 adding manifests
894 adding file changes
905 adding file changes
895 added 2 changesets with 2 changes to 1 files
906 added 2 changesets with 2 changes to 1 files
907 no changes found
908 adding remote bookmark head1
896 updating working directory
909 updating working directory
897 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
910 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
898 no changes found
899 adding remote bookmark head1
900
911
901 $ hg -R share-1arev log -G
912 $ hg -R share-1arev log -G
902 @ changeset: 1:4a8dc1ab4c13
913 @ changeset: 1:4a8dc1ab4c13
903 | bookmark: head1
914 | bookmark: head1
904 | tag: tip
915 | tag: tip
905 | user: test
916 | user: test
906 | date: Thu Jan 01 00:00:00 1970 +0000
917 | date: Thu Jan 01 00:00:00 1970 +0000
907 | summary: head1
918 | summary: head1
908 |
919 |
909 o changeset: 0:b5f04eac9d8f
920 o changeset: 0:b5f04eac9d8f
910 user: test
921 user: test
911 date: Thu Jan 01 00:00:00 1970 +0000
922 date: Thu Jan 01 00:00:00 1970 +0000
912 summary: initial
923 summary: initial
913
924
914
925
915 making another clone should only pull down requested rev
926 making another clone should only pull down requested rev
916
927
917 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
928 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
918 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
929 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
919 updating working directory
920 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
921 searching for changes
930 searching for changes
922 adding changesets
931 adding changesets
923 adding manifests
932 adding manifests
924 adding file changes
933 adding file changes
925 added 1 changesets with 1 changes to 1 files (+1 heads)
934 added 1 changesets with 1 changes to 1 files (+1 heads)
926 adding remote bookmark head1
935 adding remote bookmark head1
927 adding remote bookmark head2
936 adding remote bookmark head2
937 updating working directory
938 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
928
939
929 $ hg -R share-1brev log -G
940 $ hg -R share-1brev log -G
930 o changeset: 2:99f71071f117
941 @ changeset: 2:99f71071f117
931 | bookmark: head2
942 | bookmark: head2
932 | tag: tip
943 | tag: tip
933 | parent: 0:b5f04eac9d8f
944 | parent: 0:b5f04eac9d8f
934 | user: test
945 | user: test
935 | date: Thu Jan 01 00:00:00 1970 +0000
946 | date: Thu Jan 01 00:00:00 1970 +0000
936 | summary: head2
947 | summary: head2
937 |
948 |
938 | @ changeset: 1:4a8dc1ab4c13
949 | o changeset: 1:4a8dc1ab4c13
939 |/ bookmark: head1
950 |/ bookmark: head1
940 | user: test
951 | user: test
941 | date: Thu Jan 01 00:00:00 1970 +0000
952 | date: Thu Jan 01 00:00:00 1970 +0000
942 | summary: head1
953 | summary: head1
943 |
954 |
944 o changeset: 0:b5f04eac9d8f
955 o changeset: 0:b5f04eac9d8f
945 user: test
956 user: test
946 date: Thu Jan 01 00:00:00 1970 +0000
957 date: Thu Jan 01 00:00:00 1970 +0000
947 summary: initial
958 summary: initial
948
959
949
960
950 Request to clone a single branch is respected in sharing mode
961 Request to clone a single branch is respected in sharing mode
951
962
952 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
963 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
953 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
964 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
954 adding changesets
965 adding changesets
955 adding manifests
966 adding manifests
956 adding file changes
967 adding file changes
957 added 2 changesets with 2 changes to 1 files
968 added 2 changesets with 2 changes to 1 files
969 no changes found
958 updating working directory
970 updating working directory
959 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
971 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
960 no changes found
961
972
962 $ hg -R share-1bbranch1 log -G
973 $ hg -R share-1bbranch1 log -G
963 o changeset: 1:5f92a6c1a1b1
974 o changeset: 1:5f92a6c1a1b1
964 | branch: branch1
975 | branch: branch1
965 | tag: tip
976 | tag: tip
966 | user: test
977 | user: test
967 | date: Thu Jan 01 00:00:00 1970 +0000
978 | date: Thu Jan 01 00:00:00 1970 +0000
968 | summary: branch1
979 | summary: branch1
969 |
980 |
970 @ changeset: 0:b5f04eac9d8f
981 @ changeset: 0:b5f04eac9d8f
971 user: test
982 user: test
972 date: Thu Jan 01 00:00:00 1970 +0000
983 date: Thu Jan 01 00:00:00 1970 +0000
973 summary: initial
984 summary: initial
974
985
975
986
976 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
987 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
977 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
988 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
978 updating working directory
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
980 searching for changes
989 searching for changes
981 adding changesets
990 adding changesets
982 adding manifests
991 adding manifests
983 adding file changes
992 adding file changes
984 added 1 changesets with 1 changes to 1 files (+1 heads)
993 added 1 changesets with 1 changes to 1 files (+1 heads)
994 updating working directory
995 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
985
996
986 $ hg -R share-1bbranch2 log -G
997 $ hg -R share-1bbranch2 log -G
987 o changeset: 2:6bacf4683960
998 o changeset: 2:6bacf4683960
988 | branch: branch2
999 | branch: branch2
989 | tag: tip
1000 | tag: tip
990 | parent: 0:b5f04eac9d8f
1001 | parent: 0:b5f04eac9d8f
991 | user: test
1002 | user: test
992 | date: Thu Jan 01 00:00:00 1970 +0000
1003 | date: Thu Jan 01 00:00:00 1970 +0000
993 | summary: branch2
1004 | summary: branch2
994 |
1005 |
995 | o changeset: 1:5f92a6c1a1b1
1006 | o changeset: 1:5f92a6c1a1b1
996 |/ branch: branch1
1007 |/ branch: branch1
997 | user: test
1008 | user: test
998 | date: Thu Jan 01 00:00:00 1970 +0000
1009 | date: Thu Jan 01 00:00:00 1970 +0000
999 | summary: branch1
1010 | summary: branch1
1000 |
1011 |
1001 @ changeset: 0:b5f04eac9d8f
1012 @ changeset: 0:b5f04eac9d8f
1002 user: test
1013 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1014 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: initial
1015 summary: initial
1005
1016
1006
1017
1007 -U is respected in share clone mode
1018 -U is respected in share clone mode
1008
1019
1009 $ hg --config share.pool=share clone -U source1a share-1anowc
1020 $ hg --config share.pool=share clone -U source1a share-1anowc
1010 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1021 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1011 searching for changes
1022 searching for changes
1012 no changes found
1023 no changes found
1013 adding remote bookmark bookA
1024 adding remote bookmark bookA
1014
1025
1015 $ ls share-1anowc
1026 $ ls share-1anowc
1016
1027
1017 Test that auto sharing doesn't cause failure of "hg clone local remote"
1028 Test that auto sharing doesn't cause failure of "hg clone local remote"
1018
1029
1019 $ cd $TESTTMP
1030 $ cd $TESTTMP
1020 $ hg -R a id -r 0
1031 $ hg -R a id -r 0
1021 acb14030fe0a
1032 acb14030fe0a
1022 $ hg id -R remote -r 0
1033 $ hg id -R remote -r 0
1023 abort: repository remote not found!
1034 abort: repository remote not found!
1024 [255]
1035 [255]
1025 $ hg --config share.pool=share -q clone -e "python \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1036 $ hg --config share.pool=share -q clone -e "python \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1026 $ hg -R remote id -r 0
1037 $ hg -R remote id -r 0
1027 acb14030fe0a
1038 acb14030fe0a
1028
1039
1029 Cloning into pooled storage doesn't race (issue5104)
1040 Cloning into pooled storage doesn't race (issue5104)
1030
1041
1031 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1042 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1032 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1043 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1033 $ wait
1044 $ wait
1034
1045
1035 $ hg -R share-destrace1 log -r tip
1046 $ hg -R share-destrace1 log -r tip
1036 changeset: 2:e5bfe23c0b47
1047 changeset: 2:e5bfe23c0b47
1037 bookmark: bookA
1048 bookmark: bookA
1038 tag: tip
1049 tag: tip
1039 user: test
1050 user: test
1040 date: Thu Jan 01 00:00:00 1970 +0000
1051 date: Thu Jan 01 00:00:00 1970 +0000
1041 summary: 1a
1052 summary: 1a
1042
1053
1043
1054
1044 $ hg -R share-destrace2 log -r tip
1055 $ hg -R share-destrace2 log -r tip
1045 changeset: 2:e5bfe23c0b47
1056 changeset: 2:e5bfe23c0b47
1046 bookmark: bookA
1057 bookmark: bookA
1047 tag: tip
1058 tag: tip
1048 user: test
1059 user: test
1049 date: Thu Jan 01 00:00:00 1970 +0000
1060 date: Thu Jan 01 00:00:00 1970 +0000
1050 summary: 1a
1061 summary: 1a
1051
1062
1052 $ cat race1.log
1063 $ cat race1.log
1053 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1064 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1054 requesting all changes
1065 requesting all changes
1055 adding changesets
1066 adding changesets
1056 adding manifests
1067 adding manifests
1057 adding file changes
1068 adding file changes
1058 added 3 changesets with 3 changes to 1 files
1069 added 3 changesets with 3 changes to 1 files
1059 updating working directory
1060 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1061 searching for changes
1070 searching for changes
1062 no changes found
1071 no changes found
1063 adding remote bookmark bookA
1072 adding remote bookmark bookA
1073 updating working directory
1074 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1064
1075
1065 $ cat race2.log
1076 $ cat race2.log
1066 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1077 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1067 updating working directory
1068 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1069 waiting for lock on repository share-destrace2 held by * (glob)
1078 waiting for lock on repository share-destrace2 held by * (glob)
1070 got lock after \d+ seconds (re)
1079 got lock after \d+ seconds (re)
1071 searching for changes
1080 searching for changes
1072 no changes found
1081 no changes found
1073 adding remote bookmark bookA
1082 adding remote bookmark bookA
1083 updating working directory
1084 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now