##// END OF EJS Templates
copystore: provide unit to ui.makeprogress()
av6 -
r40671:e5f54c4e stable
parent child Browse files
Show More
@@ -1,1229 +1,1229 b''
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 hashlib
12 import hashlib
13 import os
13 import os
14 import shutil
14 import shutil
15 import stat
15 import stat
16
16
17 from .i18n import _
17 from .i18n import _
18 from .node import (
18 from .node import (
19 nullid,
19 nullid,
20 )
20 )
21
21
22 from . import (
22 from . import (
23 bookmarks,
23 bookmarks,
24 bundlerepo,
24 bundlerepo,
25 cacheutil,
25 cacheutil,
26 cmdutil,
26 cmdutil,
27 destutil,
27 destutil,
28 discovery,
28 discovery,
29 error,
29 error,
30 exchange,
30 exchange,
31 extensions,
31 extensions,
32 httppeer,
32 httppeer,
33 localrepo,
33 localrepo,
34 lock,
34 lock,
35 logcmdutil,
35 logcmdutil,
36 logexchange,
36 logexchange,
37 merge as mergemod,
37 merge as mergemod,
38 narrowspec,
38 narrowspec,
39 node,
39 node,
40 phases,
40 phases,
41 scmutil,
41 scmutil,
42 sshpeer,
42 sshpeer,
43 statichttprepo,
43 statichttprepo,
44 ui as uimod,
44 ui as uimod,
45 unionrepo,
45 unionrepo,
46 url,
46 url,
47 util,
47 util,
48 verify as verifymod,
48 verify as verifymod,
49 vfs as vfsmod,
49 vfs as vfsmod,
50 )
50 )
51
51
52 release = lock.release
52 release = lock.release
53
53
54 # shared features
54 # shared features
55 sharedbookmarks = 'bookmarks'
55 sharedbookmarks = 'bookmarks'
56
56
57 def _local(path):
57 def _local(path):
58 path = util.expandpath(util.urllocalpath(path))
58 path = util.expandpath(util.urllocalpath(path))
59 return (os.path.isfile(path) and bundlerepo or localrepo)
59 return (os.path.isfile(path) and bundlerepo or localrepo)
60
60
61 def addbranchrevs(lrepo, other, branches, revs):
61 def addbranchrevs(lrepo, other, branches, revs):
62 peer = other.peer() # a courtesy to callers using a localrepo for other
62 peer = other.peer() # a courtesy to callers using a localrepo for other
63 hashbranch, branches = branches
63 hashbranch, branches = branches
64 if not hashbranch and not branches:
64 if not hashbranch and not branches:
65 x = revs or None
65 x = revs or None
66 if revs:
66 if revs:
67 y = revs[0]
67 y = revs[0]
68 else:
68 else:
69 y = None
69 y = None
70 return x, y
70 return x, y
71 if revs:
71 if revs:
72 revs = list(revs)
72 revs = list(revs)
73 else:
73 else:
74 revs = []
74 revs = []
75
75
76 if not peer.capable('branchmap'):
76 if not peer.capable('branchmap'):
77 if branches:
77 if branches:
78 raise error.Abort(_("remote branch lookup not supported"))
78 raise error.Abort(_("remote branch lookup not supported"))
79 revs.append(hashbranch)
79 revs.append(hashbranch)
80 return revs, revs[0]
80 return revs, revs[0]
81
81
82 with peer.commandexecutor() as e:
82 with peer.commandexecutor() as e:
83 branchmap = e.callcommand('branchmap', {}).result()
83 branchmap = e.callcommand('branchmap', {}).result()
84
84
85 def primary(branch):
85 def primary(branch):
86 if branch == '.':
86 if branch == '.':
87 if not lrepo:
87 if not lrepo:
88 raise error.Abort(_("dirstate branch not accessible"))
88 raise error.Abort(_("dirstate branch not accessible"))
89 branch = lrepo.dirstate.branch()
89 branch = lrepo.dirstate.branch()
90 if branch in branchmap:
90 if branch in branchmap:
91 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
91 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
92 return True
92 return True
93 else:
93 else:
94 return False
94 return False
95
95
96 for branch in branches:
96 for branch in branches:
97 if not primary(branch):
97 if not primary(branch):
98 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
98 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
99 if hashbranch:
99 if hashbranch:
100 if not primary(hashbranch):
100 if not primary(hashbranch):
101 revs.append(hashbranch)
101 revs.append(hashbranch)
102 return revs, revs[0]
102 return revs, revs[0]
103
103
104 def parseurl(path, branches=None):
104 def parseurl(path, branches=None):
105 '''parse url#branch, returning (url, (branch, branches))'''
105 '''parse url#branch, returning (url, (branch, branches))'''
106
106
107 u = util.url(path)
107 u = util.url(path)
108 branch = None
108 branch = None
109 if u.fragment:
109 if u.fragment:
110 branch = u.fragment
110 branch = u.fragment
111 u.fragment = None
111 u.fragment = None
112 return bytes(u), (branch, branches or [])
112 return bytes(u), (branch, branches or [])
113
113
114 schemes = {
114 schemes = {
115 'bundle': bundlerepo,
115 'bundle': bundlerepo,
116 'union': unionrepo,
116 'union': unionrepo,
117 'file': _local,
117 'file': _local,
118 'http': httppeer,
118 'http': httppeer,
119 'https': httppeer,
119 'https': httppeer,
120 'ssh': sshpeer,
120 'ssh': sshpeer,
121 'static-http': statichttprepo,
121 'static-http': statichttprepo,
122 }
122 }
123
123
124 def _peerlookup(path):
124 def _peerlookup(path):
125 u = util.url(path)
125 u = util.url(path)
126 scheme = u.scheme or 'file'
126 scheme = u.scheme or 'file'
127 thing = schemes.get(scheme) or schemes['file']
127 thing = schemes.get(scheme) or schemes['file']
128 try:
128 try:
129 return thing(path)
129 return thing(path)
130 except TypeError:
130 except TypeError:
131 # we can't test callable(thing) because 'thing' can be an unloaded
131 # we can't test callable(thing) because 'thing' can be an unloaded
132 # module that implements __call__
132 # module that implements __call__
133 if not util.safehasattr(thing, 'instance'):
133 if not util.safehasattr(thing, 'instance'):
134 raise
134 raise
135 return thing
135 return thing
136
136
137 def islocal(repo):
137 def islocal(repo):
138 '''return true if repo (or path pointing to repo) is local'''
138 '''return true if repo (or path pointing to repo) is local'''
139 if isinstance(repo, bytes):
139 if isinstance(repo, bytes):
140 try:
140 try:
141 return _peerlookup(repo).islocal(repo)
141 return _peerlookup(repo).islocal(repo)
142 except AttributeError:
142 except AttributeError:
143 return False
143 return False
144 return repo.local()
144 return repo.local()
145
145
146 def openpath(ui, path):
146 def openpath(ui, path):
147 '''open path with open if local, url.open if remote'''
147 '''open path with open if local, url.open if remote'''
148 pathurl = util.url(path, parsequery=False, parsefragment=False)
148 pathurl = util.url(path, parsequery=False, parsefragment=False)
149 if pathurl.islocal():
149 if pathurl.islocal():
150 return util.posixfile(pathurl.localpath(), 'rb')
150 return util.posixfile(pathurl.localpath(), 'rb')
151 else:
151 else:
152 return url.open(ui, path)
152 return url.open(ui, path)
153
153
154 # a list of (ui, repo) functions called for wire peer initialization
154 # a list of (ui, repo) functions called for wire peer initialization
155 wirepeersetupfuncs = []
155 wirepeersetupfuncs = []
156
156
157 def _peerorrepo(ui, path, create=False, presetupfuncs=None,
157 def _peerorrepo(ui, path, create=False, presetupfuncs=None,
158 intents=None, createopts=None):
158 intents=None, createopts=None):
159 """return a repository object for the specified path"""
159 """return a repository object for the specified path"""
160 obj = _peerlookup(path).instance(ui, path, create, intents=intents,
160 obj = _peerlookup(path).instance(ui, path, create, intents=intents,
161 createopts=createopts)
161 createopts=createopts)
162 ui = getattr(obj, "ui", ui)
162 ui = getattr(obj, "ui", ui)
163 if ui.configbool('devel', 'debug.extensions'):
163 if ui.configbool('devel', 'debug.extensions'):
164 log = lambda msg, *values: ui.debug('debug.extensions: ',
164 log = lambda msg, *values: ui.debug('debug.extensions: ',
165 msg % values, label='debug.extensions')
165 msg % values, label='debug.extensions')
166 else:
166 else:
167 log = lambda *a, **kw: None
167 log = lambda *a, **kw: None
168 for f in presetupfuncs or []:
168 for f in presetupfuncs or []:
169 f(ui, obj)
169 f(ui, obj)
170 log('- executing reposetup hooks\n')
170 log('- executing reposetup hooks\n')
171 with util.timedcm('all reposetup') as allreposetupstats:
171 with util.timedcm('all reposetup') as allreposetupstats:
172 for name, module in extensions.extensions(ui):
172 for name, module in extensions.extensions(ui):
173 log(' - running reposetup for %s\n' % (name,))
173 log(' - running reposetup for %s\n' % (name,))
174 hook = getattr(module, 'reposetup', None)
174 hook = getattr(module, 'reposetup', None)
175 if hook:
175 if hook:
176 with util.timedcm('reposetup %r', name) as stats:
176 with util.timedcm('reposetup %r', name) as stats:
177 hook(ui, obj)
177 hook(ui, obj)
178 log(' > reposetup for %r took %s\n', name, stats)
178 log(' > reposetup for %r took %s\n', name, stats)
179 log('> all reposetup took %s\n', allreposetupstats)
179 log('> all reposetup took %s\n', allreposetupstats)
180 if not obj.local():
180 if not obj.local():
181 for f in wirepeersetupfuncs:
181 for f in wirepeersetupfuncs:
182 f(ui, obj)
182 f(ui, obj)
183 return obj
183 return obj
184
184
185 def repository(ui, path='', create=False, presetupfuncs=None, intents=None,
185 def repository(ui, path='', create=False, presetupfuncs=None, intents=None,
186 createopts=None):
186 createopts=None):
187 """return a repository object for the specified path"""
187 """return a repository object for the specified path"""
188 peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs,
188 peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs,
189 intents=intents, createopts=createopts)
189 intents=intents, createopts=createopts)
190 repo = peer.local()
190 repo = peer.local()
191 if not repo:
191 if not repo:
192 raise error.Abort(_("repository '%s' is not local") %
192 raise error.Abort(_("repository '%s' is not local") %
193 (path or peer.url()))
193 (path or peer.url()))
194 return repo.filtered('visible')
194 return repo.filtered('visible')
195
195
196 def peer(uiorrepo, opts, path, create=False, intents=None, createopts=None):
196 def peer(uiorrepo, opts, path, create=False, intents=None, createopts=None):
197 '''return a repository peer for the specified path'''
197 '''return a repository peer for the specified path'''
198 rui = remoteui(uiorrepo, opts)
198 rui = remoteui(uiorrepo, opts)
199 return _peerorrepo(rui, path, create, intents=intents,
199 return _peerorrepo(rui, path, create, intents=intents,
200 createopts=createopts).peer()
200 createopts=createopts).peer()
201
201
202 def defaultdest(source):
202 def defaultdest(source):
203 '''return default destination of clone if none is given
203 '''return default destination of clone if none is given
204
204
205 >>> defaultdest(b'foo')
205 >>> defaultdest(b'foo')
206 'foo'
206 'foo'
207 >>> defaultdest(b'/foo/bar')
207 >>> defaultdest(b'/foo/bar')
208 'bar'
208 'bar'
209 >>> defaultdest(b'/')
209 >>> defaultdest(b'/')
210 ''
210 ''
211 >>> defaultdest(b'')
211 >>> defaultdest(b'')
212 ''
212 ''
213 >>> defaultdest(b'http://example.org/')
213 >>> defaultdest(b'http://example.org/')
214 ''
214 ''
215 >>> defaultdest(b'http://example.org/foo/')
215 >>> defaultdest(b'http://example.org/foo/')
216 'foo'
216 'foo'
217 '''
217 '''
218 path = util.url(source).path
218 path = util.url(source).path
219 if not path:
219 if not path:
220 return ''
220 return ''
221 return os.path.basename(os.path.normpath(path))
221 return os.path.basename(os.path.normpath(path))
222
222
223 def sharedreposource(repo):
223 def sharedreposource(repo):
224 """Returns repository object for source repository of a shared repo.
224 """Returns repository object for source repository of a shared repo.
225
225
226 If repo is not a shared repository, returns None.
226 If repo is not a shared repository, returns None.
227 """
227 """
228 if repo.sharedpath == repo.path:
228 if repo.sharedpath == repo.path:
229 return None
229 return None
230
230
231 if util.safehasattr(repo, 'srcrepo') and repo.srcrepo:
231 if util.safehasattr(repo, 'srcrepo') and repo.srcrepo:
232 return repo.srcrepo
232 return repo.srcrepo
233
233
234 # the sharedpath always ends in the .hg; we want the path to the repo
234 # the sharedpath always ends in the .hg; we want the path to the repo
235 source = repo.vfs.split(repo.sharedpath)[0]
235 source = repo.vfs.split(repo.sharedpath)[0]
236 srcurl, branches = parseurl(source)
236 srcurl, branches = parseurl(source)
237 srcrepo = repository(repo.ui, srcurl)
237 srcrepo = repository(repo.ui, srcurl)
238 repo.srcrepo = srcrepo
238 repo.srcrepo = srcrepo
239 return srcrepo
239 return srcrepo
240
240
241 def share(ui, source, dest=None, update=True, bookmarks=True, defaultpath=None,
241 def share(ui, source, dest=None, update=True, bookmarks=True, defaultpath=None,
242 relative=False):
242 relative=False):
243 '''create a shared repository'''
243 '''create a shared repository'''
244
244
245 if not islocal(source):
245 if not islocal(source):
246 raise error.Abort(_('can only share local repositories'))
246 raise error.Abort(_('can only share local repositories'))
247
247
248 if not dest:
248 if not dest:
249 dest = defaultdest(source)
249 dest = defaultdest(source)
250 else:
250 else:
251 dest = ui.expandpath(dest)
251 dest = ui.expandpath(dest)
252
252
253 if isinstance(source, bytes):
253 if isinstance(source, bytes):
254 origsource = ui.expandpath(source)
254 origsource = ui.expandpath(source)
255 source, branches = parseurl(origsource)
255 source, branches = parseurl(origsource)
256 srcrepo = repository(ui, source)
256 srcrepo = repository(ui, source)
257 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
257 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
258 else:
258 else:
259 srcrepo = source.local()
259 srcrepo = source.local()
260 checkout = None
260 checkout = None
261
261
262 shareditems = set()
262 shareditems = set()
263 if bookmarks:
263 if bookmarks:
264 shareditems.add(sharedbookmarks)
264 shareditems.add(sharedbookmarks)
265
265
266 r = repository(ui, dest, create=True, createopts={
266 r = repository(ui, dest, create=True, createopts={
267 'sharedrepo': srcrepo,
267 'sharedrepo': srcrepo,
268 'sharedrelative': relative,
268 'sharedrelative': relative,
269 'shareditems': shareditems,
269 'shareditems': shareditems,
270 })
270 })
271
271
272 postshare(srcrepo, r, defaultpath=defaultpath)
272 postshare(srcrepo, r, defaultpath=defaultpath)
273 _postshareupdate(r, update, checkout=checkout)
273 _postshareupdate(r, update, checkout=checkout)
274 return r
274 return r
275
275
276 def unshare(ui, repo):
276 def unshare(ui, repo):
277 """convert a shared repository to a normal one
277 """convert a shared repository to a normal one
278
278
279 Copy the store data to the repo and remove the sharedpath data.
279 Copy the store data to the repo and remove the sharedpath data.
280
280
281 Returns a new repository object representing the unshared repository.
281 Returns a new repository object representing the unshared repository.
282
282
283 The passed repository object is not usable after this function is
283 The passed repository object is not usable after this function is
284 called.
284 called.
285 """
285 """
286
286
287 destlock = lock = None
287 destlock = lock = None
288 lock = repo.lock()
288 lock = repo.lock()
289 try:
289 try:
290 # we use locks here because if we race with commit, we
290 # we use locks here because if we race with commit, we
291 # can end up with extra data in the cloned revlogs that's
291 # can end up with extra data in the cloned revlogs that's
292 # not pointed to by changesets, thus causing verify to
292 # not pointed to by changesets, thus causing verify to
293 # fail
293 # fail
294
294
295 destlock = copystore(ui, repo, repo.path)
295 destlock = copystore(ui, repo, repo.path)
296
296
297 sharefile = repo.vfs.join('sharedpath')
297 sharefile = repo.vfs.join('sharedpath')
298 util.rename(sharefile, sharefile + '.old')
298 util.rename(sharefile, sharefile + '.old')
299
299
300 repo.requirements.discard('shared')
300 repo.requirements.discard('shared')
301 repo.requirements.discard('relshared')
301 repo.requirements.discard('relshared')
302 repo._writerequirements()
302 repo._writerequirements()
303 finally:
303 finally:
304 destlock and destlock.release()
304 destlock and destlock.release()
305 lock and lock.release()
305 lock and lock.release()
306
306
307 # Removing share changes some fundamental properties of the repo instance.
307 # Removing share changes some fundamental properties of the repo instance.
308 # So we instantiate a new repo object and operate on it rather than
308 # So we instantiate a new repo object and operate on it rather than
309 # try to keep the existing repo usable.
309 # try to keep the existing repo usable.
310 newrepo = repository(repo.baseui, repo.root, create=False)
310 newrepo = repository(repo.baseui, repo.root, create=False)
311
311
312 # TODO: figure out how to access subrepos that exist, but were previously
312 # TODO: figure out how to access subrepos that exist, but were previously
313 # removed from .hgsub
313 # removed from .hgsub
314 c = newrepo['.']
314 c = newrepo['.']
315 subs = c.substate
315 subs = c.substate
316 for s in sorted(subs):
316 for s in sorted(subs):
317 c.sub(s).unshare()
317 c.sub(s).unshare()
318
318
319 localrepo.poisonrepository(repo)
319 localrepo.poisonrepository(repo)
320
320
321 return newrepo
321 return newrepo
322
322
323 def postshare(sourcerepo, destrepo, defaultpath=None):
323 def postshare(sourcerepo, destrepo, defaultpath=None):
324 """Called after a new shared repo is created.
324 """Called after a new shared repo is created.
325
325
326 The new repo only has a requirements file and pointer to the source.
326 The new repo only has a requirements file and pointer to the source.
327 This function configures additional shared data.
327 This function configures additional shared data.
328
328
329 Extensions can wrap this function and write additional entries to
329 Extensions can wrap this function and write additional entries to
330 destrepo/.hg/shared to indicate additional pieces of data to be shared.
330 destrepo/.hg/shared to indicate additional pieces of data to be shared.
331 """
331 """
332 default = defaultpath or sourcerepo.ui.config('paths', 'default')
332 default = defaultpath or sourcerepo.ui.config('paths', 'default')
333 if default:
333 if default:
334 template = ('[paths]\n'
334 template = ('[paths]\n'
335 'default = %s\n')
335 'default = %s\n')
336 destrepo.vfs.write('hgrc', util.tonativeeol(template % default))
336 destrepo.vfs.write('hgrc', util.tonativeeol(template % default))
337
337
338 def _postshareupdate(repo, update, checkout=None):
338 def _postshareupdate(repo, update, checkout=None):
339 """Maybe perform a working directory update after a shared repo is created.
339 """Maybe perform a working directory update after a shared repo is created.
340
340
341 ``update`` can be a boolean or a revision to update to.
341 ``update`` can be a boolean or a revision to update to.
342 """
342 """
343 if not update:
343 if not update:
344 return
344 return
345
345
346 repo.ui.status(_("updating working directory\n"))
346 repo.ui.status(_("updating working directory\n"))
347 if update is not True:
347 if update is not True:
348 checkout = update
348 checkout = update
349 for test in (checkout, 'default', 'tip'):
349 for test in (checkout, 'default', 'tip'):
350 if test is None:
350 if test is None:
351 continue
351 continue
352 try:
352 try:
353 uprev = repo.lookup(test)
353 uprev = repo.lookup(test)
354 break
354 break
355 except error.RepoLookupError:
355 except error.RepoLookupError:
356 continue
356 continue
357 _update(repo, uprev)
357 _update(repo, uprev)
358
358
359 def copystore(ui, srcrepo, destpath):
359 def copystore(ui, srcrepo, destpath):
360 '''copy files from store of srcrepo in destpath
360 '''copy files from store of srcrepo in destpath
361
361
362 returns destlock
362 returns destlock
363 '''
363 '''
364 destlock = None
364 destlock = None
365 try:
365 try:
366 hardlink = None
366 hardlink = None
367 topic = _('linking') if hardlink else _('copying')
367 topic = _('linking') if hardlink else _('copying')
368 with ui.makeprogress(topic) as progress:
368 with ui.makeprogress(topic, unit=_('files')) as progress:
369 num = 0
369 num = 0
370 srcpublishing = srcrepo.publishing()
370 srcpublishing = srcrepo.publishing()
371 srcvfs = vfsmod.vfs(srcrepo.sharedpath)
371 srcvfs = vfsmod.vfs(srcrepo.sharedpath)
372 dstvfs = vfsmod.vfs(destpath)
372 dstvfs = vfsmod.vfs(destpath)
373 for f in srcrepo.store.copylist():
373 for f in srcrepo.store.copylist():
374 if srcpublishing and f.endswith('phaseroots'):
374 if srcpublishing and f.endswith('phaseroots'):
375 continue
375 continue
376 dstbase = os.path.dirname(f)
376 dstbase = os.path.dirname(f)
377 if dstbase and not dstvfs.exists(dstbase):
377 if dstbase and not dstvfs.exists(dstbase):
378 dstvfs.mkdir(dstbase)
378 dstvfs.mkdir(dstbase)
379 if srcvfs.exists(f):
379 if srcvfs.exists(f):
380 if f.endswith('data'):
380 if f.endswith('data'):
381 # 'dstbase' may be empty (e.g. revlog format 0)
381 # 'dstbase' may be empty (e.g. revlog format 0)
382 lockfile = os.path.join(dstbase, "lock")
382 lockfile = os.path.join(dstbase, "lock")
383 # lock to avoid premature writing to the target
383 # lock to avoid premature writing to the target
384 destlock = lock.lock(dstvfs, lockfile)
384 destlock = lock.lock(dstvfs, lockfile)
385 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
385 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
386 hardlink, progress)
386 hardlink, progress)
387 num += n
387 num += n
388 if hardlink:
388 if hardlink:
389 ui.debug("linked %d files\n" % num)
389 ui.debug("linked %d files\n" % num)
390 else:
390 else:
391 ui.debug("copied %d files\n" % num)
391 ui.debug("copied %d files\n" % num)
392 return destlock
392 return destlock
393 except: # re-raises
393 except: # re-raises
394 release(destlock)
394 release(destlock)
395 raise
395 raise
396
396
397 def clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=False,
397 def clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=False,
398 rev=None, update=True, stream=False):
398 rev=None, update=True, stream=False):
399 """Perform a clone using a shared repo.
399 """Perform a clone using a shared repo.
400
400
401 The store for the repository will be located at <sharepath>/.hg. The
401 The store for the repository will be located at <sharepath>/.hg. The
402 specified revisions will be cloned or pulled from "source". A shared repo
402 specified revisions will be cloned or pulled from "source". A shared repo
403 will be created at "dest" and a working copy will be created if "update" is
403 will be created at "dest" and a working copy will be created if "update" is
404 True.
404 True.
405 """
405 """
406 revs = None
406 revs = None
407 if rev:
407 if rev:
408 if not srcpeer.capable('lookup'):
408 if not srcpeer.capable('lookup'):
409 raise error.Abort(_("src repository does not support "
409 raise error.Abort(_("src repository does not support "
410 "revision lookup and so doesn't "
410 "revision lookup and so doesn't "
411 "support clone by revision"))
411 "support clone by revision"))
412
412
413 # TODO this is batchable.
413 # TODO this is batchable.
414 remoterevs = []
414 remoterevs = []
415 for r in rev:
415 for r in rev:
416 with srcpeer.commandexecutor() as e:
416 with srcpeer.commandexecutor() as e:
417 remoterevs.append(e.callcommand('lookup', {
417 remoterevs.append(e.callcommand('lookup', {
418 'key': r,
418 'key': r,
419 }).result())
419 }).result())
420 revs = remoterevs
420 revs = remoterevs
421
421
422 # Obtain a lock before checking for or cloning the pooled repo otherwise
422 # Obtain a lock before checking for or cloning the pooled repo otherwise
423 # 2 clients may race creating or populating it.
423 # 2 clients may race creating or populating it.
424 pooldir = os.path.dirname(sharepath)
424 pooldir = os.path.dirname(sharepath)
425 # lock class requires the directory to exist.
425 # lock class requires the directory to exist.
426 try:
426 try:
427 util.makedir(pooldir, False)
427 util.makedir(pooldir, False)
428 except OSError as e:
428 except OSError as e:
429 if e.errno != errno.EEXIST:
429 if e.errno != errno.EEXIST:
430 raise
430 raise
431
431
432 poolvfs = vfsmod.vfs(pooldir)
432 poolvfs = vfsmod.vfs(pooldir)
433 basename = os.path.basename(sharepath)
433 basename = os.path.basename(sharepath)
434
434
435 with lock.lock(poolvfs, '%s.lock' % basename):
435 with lock.lock(poolvfs, '%s.lock' % basename):
436 if os.path.exists(sharepath):
436 if os.path.exists(sharepath):
437 ui.status(_('(sharing from existing pooled repository %s)\n') %
437 ui.status(_('(sharing from existing pooled repository %s)\n') %
438 basename)
438 basename)
439 else:
439 else:
440 ui.status(_('(sharing from new pooled repository %s)\n') % basename)
440 ui.status(_('(sharing from new pooled repository %s)\n') % basename)
441 # Always use pull mode because hardlinks in share mode don't work
441 # Always use pull mode because hardlinks in share mode don't work
442 # well. Never update because working copies aren't necessary in
442 # well. Never update because working copies aren't necessary in
443 # share mode.
443 # share mode.
444 clone(ui, peeropts, source, dest=sharepath, pull=True,
444 clone(ui, peeropts, source, dest=sharepath, pull=True,
445 revs=rev, update=False, stream=stream)
445 revs=rev, update=False, stream=stream)
446
446
447 # Resolve the value to put in [paths] section for the source.
447 # Resolve the value to put in [paths] section for the source.
448 if islocal(source):
448 if islocal(source):
449 defaultpath = os.path.abspath(util.urllocalpath(source))
449 defaultpath = os.path.abspath(util.urllocalpath(source))
450 else:
450 else:
451 defaultpath = source
451 defaultpath = source
452
452
453 sharerepo = repository(ui, path=sharepath)
453 sharerepo = repository(ui, path=sharepath)
454 share(ui, sharerepo, dest=dest, update=False, bookmarks=False,
454 share(ui, sharerepo, dest=dest, update=False, bookmarks=False,
455 defaultpath=defaultpath)
455 defaultpath=defaultpath)
456
456
457 # We need to perform a pull against the dest repo to fetch bookmarks
457 # We need to perform a pull against the dest repo to fetch bookmarks
458 # and other non-store data that isn't shared by default. In the case of
458 # and other non-store data that isn't shared by default. In the case of
459 # non-existing shared repo, this means we pull from the remote twice. This
459 # non-existing shared repo, this means we pull from the remote twice. This
460 # is a bit weird. But at the time it was implemented, there wasn't an easy
460 # is a bit weird. But at the time it was implemented, there wasn't an easy
461 # way to pull just non-changegroup data.
461 # way to pull just non-changegroup data.
462 destrepo = repository(ui, path=dest)
462 destrepo = repository(ui, path=dest)
463 exchange.pull(destrepo, srcpeer, heads=revs)
463 exchange.pull(destrepo, srcpeer, heads=revs)
464
464
465 _postshareupdate(destrepo, update)
465 _postshareupdate(destrepo, update)
466
466
467 return srcpeer, peer(ui, peeropts, dest)
467 return srcpeer, peer(ui, peeropts, dest)
468
468
469 # Recomputing branch cache might be slow on big repos,
469 # Recomputing branch cache might be slow on big repos,
470 # so just copy it
470 # so just copy it
471 def _copycache(srcrepo, dstcachedir, fname):
471 def _copycache(srcrepo, dstcachedir, fname):
472 """copy a cache from srcrepo to destcachedir (if it exists)"""
472 """copy a cache from srcrepo to destcachedir (if it exists)"""
473 srcbranchcache = srcrepo.vfs.join('cache/%s' % fname)
473 srcbranchcache = srcrepo.vfs.join('cache/%s' % fname)
474 dstbranchcache = os.path.join(dstcachedir, fname)
474 dstbranchcache = os.path.join(dstcachedir, fname)
475 if os.path.exists(srcbranchcache):
475 if os.path.exists(srcbranchcache):
476 if not os.path.exists(dstcachedir):
476 if not os.path.exists(dstcachedir):
477 os.mkdir(dstcachedir)
477 os.mkdir(dstcachedir)
478 util.copyfile(srcbranchcache, dstbranchcache)
478 util.copyfile(srcbranchcache, dstbranchcache)
479
479
480 def clone(ui, peeropts, source, dest=None, pull=False, revs=None,
480 def clone(ui, peeropts, source, dest=None, pull=False, revs=None,
481 update=True, stream=False, branch=None, shareopts=None,
481 update=True, stream=False, branch=None, shareopts=None,
482 storeincludepats=None, storeexcludepats=None, depth=None):
482 storeincludepats=None, storeexcludepats=None, depth=None):
483 """Make a copy of an existing repository.
483 """Make a copy of an existing repository.
484
484
485 Create a copy of an existing repository in a new directory. The
485 Create a copy of an existing repository in a new directory. The
486 source and destination are URLs, as passed to the repository
486 source and destination are URLs, as passed to the repository
487 function. Returns a pair of repository peers, the source and
487 function. Returns a pair of repository peers, the source and
488 newly created destination.
488 newly created destination.
489
489
490 The location of the source is added to the new repository's
490 The location of the source is added to the new repository's
491 .hg/hgrc file, as the default to be used for future pulls and
491 .hg/hgrc file, as the default to be used for future pulls and
492 pushes.
492 pushes.
493
493
494 If an exception is raised, the partly cloned/updated destination
494 If an exception is raised, the partly cloned/updated destination
495 repository will be deleted.
495 repository will be deleted.
496
496
497 Arguments:
497 Arguments:
498
498
499 source: repository object or URL
499 source: repository object or URL
500
500
501 dest: URL of destination repository to create (defaults to base
501 dest: URL of destination repository to create (defaults to base
502 name of source repository)
502 name of source repository)
503
503
504 pull: always pull from source repository, even in local case or if the
504 pull: always pull from source repository, even in local case or if the
505 server prefers streaming
505 server prefers streaming
506
506
507 stream: stream raw data uncompressed from repository (fast over
507 stream: stream raw data uncompressed from repository (fast over
508 LAN, slow over WAN)
508 LAN, slow over WAN)
509
509
510 revs: revision to clone up to (implies pull=True)
510 revs: revision to clone up to (implies pull=True)
511
511
512 update: update working directory after clone completes, if
512 update: update working directory after clone completes, if
513 destination is local repository (True means update to default rev,
513 destination is local repository (True means update to default rev,
514 anything else is treated as a revision)
514 anything else is treated as a revision)
515
515
516 branch: branches to clone
516 branch: branches to clone
517
517
518 shareopts: dict of options to control auto sharing behavior. The "pool" key
518 shareopts: dict of options to control auto sharing behavior. The "pool" key
519 activates auto sharing mode and defines the directory for stores. The
519 activates auto sharing mode and defines the directory for stores. The
520 "mode" key determines how to construct the directory name of the shared
520 "mode" key determines how to construct the directory name of the shared
521 repository. "identity" means the name is derived from the node of the first
521 repository. "identity" means the name is derived from the node of the first
522 changeset in the repository. "remote" means the name is derived from the
522 changeset in the repository. "remote" means the name is derived from the
523 remote's path/URL. Defaults to "identity."
523 remote's path/URL. Defaults to "identity."
524
524
525 storeincludepats and storeexcludepats: sets of file patterns to include and
525 storeincludepats and storeexcludepats: sets of file patterns to include and
526 exclude in the repository copy, respectively. If not defined, all files
526 exclude in the repository copy, respectively. If not defined, all files
527 will be included (a "full" clone). Otherwise a "narrow" clone containing
527 will be included (a "full" clone). Otherwise a "narrow" clone containing
528 only the requested files will be performed. If ``storeincludepats`` is not
528 only the requested files will be performed. If ``storeincludepats`` is not
529 defined but ``storeexcludepats`` is, ``storeincludepats`` is assumed to be
529 defined but ``storeexcludepats`` is, ``storeincludepats`` is assumed to be
530 ``path:.``. If both are empty sets, no files will be cloned.
530 ``path:.``. If both are empty sets, no files will be cloned.
531 """
531 """
532
532
533 if isinstance(source, bytes):
533 if isinstance(source, bytes):
534 origsource = ui.expandpath(source)
534 origsource = ui.expandpath(source)
535 source, branches = parseurl(origsource, branch)
535 source, branches = parseurl(origsource, branch)
536 srcpeer = peer(ui, peeropts, source)
536 srcpeer = peer(ui, peeropts, source)
537 else:
537 else:
538 srcpeer = source.peer() # in case we were called with a localrepo
538 srcpeer = source.peer() # in case we were called with a localrepo
539 branches = (None, branch or [])
539 branches = (None, branch or [])
540 origsource = source = srcpeer.url()
540 origsource = source = srcpeer.url()
541 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
541 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
542
542
543 if dest is None:
543 if dest is None:
544 dest = defaultdest(source)
544 dest = defaultdest(source)
545 if dest:
545 if dest:
546 ui.status(_("destination directory: %s\n") % dest)
546 ui.status(_("destination directory: %s\n") % dest)
547 else:
547 else:
548 dest = ui.expandpath(dest)
548 dest = ui.expandpath(dest)
549
549
550 dest = util.urllocalpath(dest)
550 dest = util.urllocalpath(dest)
551 source = util.urllocalpath(source)
551 source = util.urllocalpath(source)
552
552
553 if not dest:
553 if not dest:
554 raise error.Abort(_("empty destination path is not valid"))
554 raise error.Abort(_("empty destination path is not valid"))
555
555
556 destvfs = vfsmod.vfs(dest, expandpath=True)
556 destvfs = vfsmod.vfs(dest, expandpath=True)
557 if destvfs.lexists():
557 if destvfs.lexists():
558 if not destvfs.isdir():
558 if not destvfs.isdir():
559 raise error.Abort(_("destination '%s' already exists") % dest)
559 raise error.Abort(_("destination '%s' already exists") % dest)
560 elif destvfs.listdir():
560 elif destvfs.listdir():
561 raise error.Abort(_("destination '%s' is not empty") % dest)
561 raise error.Abort(_("destination '%s' is not empty") % dest)
562
562
563 createopts = {}
563 createopts = {}
564 narrow = False
564 narrow = False
565
565
566 if storeincludepats is not None:
566 if storeincludepats is not None:
567 narrowspec.validatepatterns(storeincludepats)
567 narrowspec.validatepatterns(storeincludepats)
568 narrow = True
568 narrow = True
569
569
570 if storeexcludepats is not None:
570 if storeexcludepats is not None:
571 narrowspec.validatepatterns(storeexcludepats)
571 narrowspec.validatepatterns(storeexcludepats)
572 narrow = True
572 narrow = True
573
573
574 if narrow:
574 if narrow:
575 # Include everything by default if only exclusion patterns defined.
575 # Include everything by default if only exclusion patterns defined.
576 if storeexcludepats and not storeincludepats:
576 if storeexcludepats and not storeincludepats:
577 storeincludepats = {'path:.'}
577 storeincludepats = {'path:.'}
578
578
579 createopts['narrowfiles'] = True
579 createopts['narrowfiles'] = True
580
580
581 if depth:
581 if depth:
582 createopts['shallowfilestore'] = True
582 createopts['shallowfilestore'] = True
583
583
584 if srcpeer.capable(b'lfs-serve'):
584 if srcpeer.capable(b'lfs-serve'):
585 # Repository creation honors the config if it disabled the extension, so
585 # Repository creation honors the config if it disabled the extension, so
586 # we can't just announce that lfs will be enabled. This check avoids
586 # we can't just announce that lfs will be enabled. This check avoids
587 # saying that lfs will be enabled, and then saying it's an unknown
587 # saying that lfs will be enabled, and then saying it's an unknown
588 # feature. The lfs creation option is set in either case so that a
588 # feature. The lfs creation option is set in either case so that a
589 # requirement is added. If the extension is explicitly disabled but the
589 # requirement is added. If the extension is explicitly disabled but the
590 # requirement is set, the clone aborts early, before transferring any
590 # requirement is set, the clone aborts early, before transferring any
591 # data.
591 # data.
592 createopts['lfs'] = True
592 createopts['lfs'] = True
593
593
594 if extensions.disabledext('lfs'):
594 if extensions.disabledext('lfs'):
595 ui.status(_('(remote is using large file support (lfs), but it is '
595 ui.status(_('(remote is using large file support (lfs), but it is '
596 'explicitly disabled in the local configuration)\n'))
596 'explicitly disabled in the local configuration)\n'))
597 else:
597 else:
598 ui.status(_('(remote is using large file support (lfs); lfs will '
598 ui.status(_('(remote is using large file support (lfs); lfs will '
599 'be enabled for this repository)\n'))
599 'be enabled for this repository)\n'))
600
600
601 shareopts = shareopts or {}
601 shareopts = shareopts or {}
602 sharepool = shareopts.get('pool')
602 sharepool = shareopts.get('pool')
603 sharenamemode = shareopts.get('mode')
603 sharenamemode = shareopts.get('mode')
604 if sharepool and islocal(dest):
604 if sharepool and islocal(dest):
605 sharepath = None
605 sharepath = None
606 if sharenamemode == 'identity':
606 if sharenamemode == 'identity':
607 # Resolve the name from the initial changeset in the remote
607 # Resolve the name from the initial changeset in the remote
608 # repository. This returns nullid when the remote is empty. It
608 # repository. This returns nullid when the remote is empty. It
609 # raises RepoLookupError if revision 0 is filtered or otherwise
609 # raises RepoLookupError if revision 0 is filtered or otherwise
610 # not available. If we fail to resolve, sharing is not enabled.
610 # not available. If we fail to resolve, sharing is not enabled.
611 try:
611 try:
612 with srcpeer.commandexecutor() as e:
612 with srcpeer.commandexecutor() as e:
613 rootnode = e.callcommand('lookup', {
613 rootnode = e.callcommand('lookup', {
614 'key': '0',
614 'key': '0',
615 }).result()
615 }).result()
616
616
617 if rootnode != node.nullid:
617 if rootnode != node.nullid:
618 sharepath = os.path.join(sharepool, node.hex(rootnode))
618 sharepath = os.path.join(sharepool, node.hex(rootnode))
619 else:
619 else:
620 ui.status(_('(not using pooled storage: '
620 ui.status(_('(not using pooled storage: '
621 'remote appears to be empty)\n'))
621 'remote appears to be empty)\n'))
622 except error.RepoLookupError:
622 except error.RepoLookupError:
623 ui.status(_('(not using pooled storage: '
623 ui.status(_('(not using pooled storage: '
624 'unable to resolve identity of remote)\n'))
624 'unable to resolve identity of remote)\n'))
625 elif sharenamemode == 'remote':
625 elif sharenamemode == 'remote':
626 sharepath = os.path.join(
626 sharepath = os.path.join(
627 sharepool, node.hex(hashlib.sha1(source).digest()))
627 sharepool, node.hex(hashlib.sha1(source).digest()))
628 else:
628 else:
629 raise error.Abort(_('unknown share naming mode: %s') %
629 raise error.Abort(_('unknown share naming mode: %s') %
630 sharenamemode)
630 sharenamemode)
631
631
632 # TODO this is a somewhat arbitrary restriction.
632 # TODO this is a somewhat arbitrary restriction.
633 if narrow:
633 if narrow:
634 ui.status(_('(pooled storage not supported for narrow clones)\n'))
634 ui.status(_('(pooled storage not supported for narrow clones)\n'))
635 sharepath = None
635 sharepath = None
636
636
637 if sharepath:
637 if sharepath:
638 return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
638 return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
639 dest, pull=pull, rev=revs, update=update,
639 dest, pull=pull, rev=revs, update=update,
640 stream=stream)
640 stream=stream)
641
641
642 srclock = destlock = cleandir = None
642 srclock = destlock = cleandir = None
643 srcrepo = srcpeer.local()
643 srcrepo = srcpeer.local()
644 try:
644 try:
645 abspath = origsource
645 abspath = origsource
646 if islocal(origsource):
646 if islocal(origsource):
647 abspath = os.path.abspath(util.urllocalpath(origsource))
647 abspath = os.path.abspath(util.urllocalpath(origsource))
648
648
649 if islocal(dest):
649 if islocal(dest):
650 cleandir = dest
650 cleandir = dest
651
651
652 copy = False
652 copy = False
653 if (srcrepo and srcrepo.cancopy() and islocal(dest)
653 if (srcrepo and srcrepo.cancopy() and islocal(dest)
654 and not phases.hassecret(srcrepo)):
654 and not phases.hassecret(srcrepo)):
655 copy = not pull and not revs
655 copy = not pull and not revs
656
656
657 # TODO this is a somewhat arbitrary restriction.
657 # TODO this is a somewhat arbitrary restriction.
658 if narrow:
658 if narrow:
659 copy = False
659 copy = False
660
660
661 if copy:
661 if copy:
662 try:
662 try:
663 # we use a lock here because if we race with commit, we
663 # we use a lock here because if we race with commit, we
664 # can end up with extra data in the cloned revlogs that's
664 # can end up with extra data in the cloned revlogs that's
665 # not pointed to by changesets, thus causing verify to
665 # not pointed to by changesets, thus causing verify to
666 # fail
666 # fail
667 srclock = srcrepo.lock(wait=False)
667 srclock = srcrepo.lock(wait=False)
668 except error.LockError:
668 except error.LockError:
669 copy = False
669 copy = False
670
670
671 if copy:
671 if copy:
672 srcrepo.hook('preoutgoing', throw=True, source='clone')
672 srcrepo.hook('preoutgoing', throw=True, source='clone')
673 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
673 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
674 if not os.path.exists(dest):
674 if not os.path.exists(dest):
675 util.makedirs(dest)
675 util.makedirs(dest)
676 else:
676 else:
677 # only clean up directories we create ourselves
677 # only clean up directories we create ourselves
678 cleandir = hgdir
678 cleandir = hgdir
679 try:
679 try:
680 destpath = hgdir
680 destpath = hgdir
681 util.makedir(destpath, notindexed=True)
681 util.makedir(destpath, notindexed=True)
682 except OSError as inst:
682 except OSError as inst:
683 if inst.errno == errno.EEXIST:
683 if inst.errno == errno.EEXIST:
684 cleandir = None
684 cleandir = None
685 raise error.Abort(_("destination '%s' already exists")
685 raise error.Abort(_("destination '%s' already exists")
686 % dest)
686 % dest)
687 raise
687 raise
688
688
689 destlock = copystore(ui, srcrepo, destpath)
689 destlock = copystore(ui, srcrepo, destpath)
690 # copy bookmarks over
690 # copy bookmarks over
691 srcbookmarks = srcrepo.vfs.join('bookmarks')
691 srcbookmarks = srcrepo.vfs.join('bookmarks')
692 dstbookmarks = os.path.join(destpath, 'bookmarks')
692 dstbookmarks = os.path.join(destpath, 'bookmarks')
693 if os.path.exists(srcbookmarks):
693 if os.path.exists(srcbookmarks):
694 util.copyfile(srcbookmarks, dstbookmarks)
694 util.copyfile(srcbookmarks, dstbookmarks)
695
695
696 dstcachedir = os.path.join(destpath, 'cache')
696 dstcachedir = os.path.join(destpath, 'cache')
697 for cache in cacheutil.cachetocopy(srcrepo):
697 for cache in cacheutil.cachetocopy(srcrepo):
698 _copycache(srcrepo, dstcachedir, cache)
698 _copycache(srcrepo, dstcachedir, cache)
699
699
700 # we need to re-init the repo after manually copying the data
700 # we need to re-init the repo after manually copying the data
701 # into it
701 # into it
702 destpeer = peer(srcrepo, peeropts, dest)
702 destpeer = peer(srcrepo, peeropts, dest)
703 srcrepo.hook('outgoing', source='clone',
703 srcrepo.hook('outgoing', source='clone',
704 node=node.hex(node.nullid))
704 node=node.hex(node.nullid))
705 else:
705 else:
706 try:
706 try:
707 # only pass ui when no srcrepo
707 # only pass ui when no srcrepo
708 destpeer = peer(srcrepo or ui, peeropts, dest, create=True,
708 destpeer = peer(srcrepo or ui, peeropts, dest, create=True,
709 createopts=createopts)
709 createopts=createopts)
710 except OSError as inst:
710 except OSError as inst:
711 if inst.errno == errno.EEXIST:
711 if inst.errno == errno.EEXIST:
712 cleandir = None
712 cleandir = None
713 raise error.Abort(_("destination '%s' already exists")
713 raise error.Abort(_("destination '%s' already exists")
714 % dest)
714 % dest)
715 raise
715 raise
716
716
717 if revs:
717 if revs:
718 if not srcpeer.capable('lookup'):
718 if not srcpeer.capable('lookup'):
719 raise error.Abort(_("src repository does not support "
719 raise error.Abort(_("src repository does not support "
720 "revision lookup and so doesn't "
720 "revision lookup and so doesn't "
721 "support clone by revision"))
721 "support clone by revision"))
722
722
723 # TODO this is batchable.
723 # TODO this is batchable.
724 remoterevs = []
724 remoterevs = []
725 for rev in revs:
725 for rev in revs:
726 with srcpeer.commandexecutor() as e:
726 with srcpeer.commandexecutor() as e:
727 remoterevs.append(e.callcommand('lookup', {
727 remoterevs.append(e.callcommand('lookup', {
728 'key': rev,
728 'key': rev,
729 }).result())
729 }).result())
730 revs = remoterevs
730 revs = remoterevs
731
731
732 checkout = revs[0]
732 checkout = revs[0]
733 else:
733 else:
734 revs = None
734 revs = None
735 local = destpeer.local()
735 local = destpeer.local()
736 if local:
736 if local:
737 if narrow:
737 if narrow:
738 with local.lock():
738 with local.lock():
739 local.setnarrowpats(storeincludepats, storeexcludepats)
739 local.setnarrowpats(storeincludepats, storeexcludepats)
740
740
741 u = util.url(abspath)
741 u = util.url(abspath)
742 defaulturl = bytes(u)
742 defaulturl = bytes(u)
743 local.ui.setconfig('paths', 'default', defaulturl, 'clone')
743 local.ui.setconfig('paths', 'default', defaulturl, 'clone')
744 if not stream:
744 if not stream:
745 if pull:
745 if pull:
746 stream = False
746 stream = False
747 else:
747 else:
748 stream = None
748 stream = None
749 # internal config: ui.quietbookmarkmove
749 # internal config: ui.quietbookmarkmove
750 overrides = {('ui', 'quietbookmarkmove'): True}
750 overrides = {('ui', 'quietbookmarkmove'): True}
751 with local.ui.configoverride(overrides, 'clone'):
751 with local.ui.configoverride(overrides, 'clone'):
752 exchange.pull(local, srcpeer, revs,
752 exchange.pull(local, srcpeer, revs,
753 streamclonerequested=stream,
753 streamclonerequested=stream,
754 includepats=storeincludepats,
754 includepats=storeincludepats,
755 excludepats=storeexcludepats,
755 excludepats=storeexcludepats,
756 depth=depth)
756 depth=depth)
757 elif srcrepo:
757 elif srcrepo:
758 # TODO lift restriction once exchange.push() accepts narrow
758 # TODO lift restriction once exchange.push() accepts narrow
759 # push.
759 # push.
760 if narrow:
760 if narrow:
761 raise error.Abort(_('narrow clone not available for '
761 raise error.Abort(_('narrow clone not available for '
762 'remote destinations'))
762 'remote destinations'))
763
763
764 exchange.push(srcrepo, destpeer, revs=revs,
764 exchange.push(srcrepo, destpeer, revs=revs,
765 bookmarks=srcrepo._bookmarks.keys())
765 bookmarks=srcrepo._bookmarks.keys())
766 else:
766 else:
767 raise error.Abort(_("clone from remote to remote not supported")
767 raise error.Abort(_("clone from remote to remote not supported")
768 )
768 )
769
769
770 cleandir = None
770 cleandir = None
771
771
772 destrepo = destpeer.local()
772 destrepo = destpeer.local()
773 if destrepo:
773 if destrepo:
774 template = uimod.samplehgrcs['cloned']
774 template = uimod.samplehgrcs['cloned']
775 u = util.url(abspath)
775 u = util.url(abspath)
776 u.passwd = None
776 u.passwd = None
777 defaulturl = bytes(u)
777 defaulturl = bytes(u)
778 destrepo.vfs.write('hgrc', util.tonativeeol(template % defaulturl))
778 destrepo.vfs.write('hgrc', util.tonativeeol(template % defaulturl))
779 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
779 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
780
780
781 if ui.configbool('experimental', 'remotenames'):
781 if ui.configbool('experimental', 'remotenames'):
782 logexchange.pullremotenames(destrepo, srcpeer)
782 logexchange.pullremotenames(destrepo, srcpeer)
783
783
784 if update:
784 if update:
785 if update is not True:
785 if update is not True:
786 with srcpeer.commandexecutor() as e:
786 with srcpeer.commandexecutor() as e:
787 checkout = e.callcommand('lookup', {
787 checkout = e.callcommand('lookup', {
788 'key': update,
788 'key': update,
789 }).result()
789 }).result()
790
790
791 uprev = None
791 uprev = None
792 status = None
792 status = None
793 if checkout is not None:
793 if checkout is not None:
794 # Some extensions (at least hg-git and hg-subversion) have
794 # Some extensions (at least hg-git and hg-subversion) have
795 # a peer.lookup() implementation that returns a name instead
795 # a peer.lookup() implementation that returns a name instead
796 # of a nodeid. We work around it here until we've figured
796 # of a nodeid. We work around it here until we've figured
797 # out a better solution.
797 # out a better solution.
798 if len(checkout) == 20 and checkout in destrepo:
798 if len(checkout) == 20 and checkout in destrepo:
799 uprev = checkout
799 uprev = checkout
800 elif scmutil.isrevsymbol(destrepo, checkout):
800 elif scmutil.isrevsymbol(destrepo, checkout):
801 uprev = scmutil.revsymbol(destrepo, checkout).node()
801 uprev = scmutil.revsymbol(destrepo, checkout).node()
802 else:
802 else:
803 if update is not True:
803 if update is not True:
804 try:
804 try:
805 uprev = destrepo.lookup(update)
805 uprev = destrepo.lookup(update)
806 except error.RepoLookupError:
806 except error.RepoLookupError:
807 pass
807 pass
808 if uprev is None:
808 if uprev is None:
809 try:
809 try:
810 uprev = destrepo._bookmarks['@']
810 uprev = destrepo._bookmarks['@']
811 update = '@'
811 update = '@'
812 bn = destrepo[uprev].branch()
812 bn = destrepo[uprev].branch()
813 if bn == 'default':
813 if bn == 'default':
814 status = _("updating to bookmark @\n")
814 status = _("updating to bookmark @\n")
815 else:
815 else:
816 status = (_("updating to bookmark @ on branch %s\n")
816 status = (_("updating to bookmark @ on branch %s\n")
817 % bn)
817 % bn)
818 except KeyError:
818 except KeyError:
819 try:
819 try:
820 uprev = destrepo.branchtip('default')
820 uprev = destrepo.branchtip('default')
821 except error.RepoLookupError:
821 except error.RepoLookupError:
822 uprev = destrepo.lookup('tip')
822 uprev = destrepo.lookup('tip')
823 if not status:
823 if not status:
824 bn = destrepo[uprev].branch()
824 bn = destrepo[uprev].branch()
825 status = _("updating to branch %s\n") % bn
825 status = _("updating to branch %s\n") % bn
826 destrepo.ui.status(status)
826 destrepo.ui.status(status)
827 _update(destrepo, uprev)
827 _update(destrepo, uprev)
828 if update in destrepo._bookmarks:
828 if update in destrepo._bookmarks:
829 bookmarks.activate(destrepo, update)
829 bookmarks.activate(destrepo, update)
830 finally:
830 finally:
831 release(srclock, destlock)
831 release(srclock, destlock)
832 if cleandir is not None:
832 if cleandir is not None:
833 shutil.rmtree(cleandir, True)
833 shutil.rmtree(cleandir, True)
834 if srcpeer is not None:
834 if srcpeer is not None:
835 srcpeer.close()
835 srcpeer.close()
836 return srcpeer, destpeer
836 return srcpeer, destpeer
837
837
838 def _showstats(repo, stats, quietempty=False):
838 def _showstats(repo, stats, quietempty=False):
839 if quietempty and stats.isempty():
839 if quietempty and stats.isempty():
840 return
840 return
841 repo.ui.status(_("%d files updated, %d files merged, "
841 repo.ui.status(_("%d files updated, %d files merged, "
842 "%d files removed, %d files unresolved\n") % (
842 "%d files removed, %d files unresolved\n") % (
843 stats.updatedcount, stats.mergedcount,
843 stats.updatedcount, stats.mergedcount,
844 stats.removedcount, stats.unresolvedcount))
844 stats.removedcount, stats.unresolvedcount))
845
845
846 def updaterepo(repo, node, overwrite, updatecheck=None):
846 def updaterepo(repo, node, overwrite, updatecheck=None):
847 """Update the working directory to node.
847 """Update the working directory to node.
848
848
849 When overwrite is set, changes are clobbered, merged else
849 When overwrite is set, changes are clobbered, merged else
850
850
851 returns stats (see pydoc mercurial.merge.applyupdates)"""
851 returns stats (see pydoc mercurial.merge.applyupdates)"""
852 return mergemod.update(repo, node, branchmerge=False, force=overwrite,
852 return mergemod.update(repo, node, branchmerge=False, force=overwrite,
853 labels=['working copy', 'destination'],
853 labels=['working copy', 'destination'],
854 updatecheck=updatecheck)
854 updatecheck=updatecheck)
855
855
856 def update(repo, node, quietempty=False, updatecheck=None):
856 def update(repo, node, quietempty=False, updatecheck=None):
857 """update the working directory to node"""
857 """update the working directory to node"""
858 stats = updaterepo(repo, node, False, updatecheck=updatecheck)
858 stats = updaterepo(repo, node, False, updatecheck=updatecheck)
859 _showstats(repo, stats, quietempty)
859 _showstats(repo, stats, quietempty)
860 if stats.unresolvedcount:
860 if stats.unresolvedcount:
861 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
861 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
862 return stats.unresolvedcount > 0
862 return stats.unresolvedcount > 0
863
863
864 # naming conflict in clone()
864 # naming conflict in clone()
865 _update = update
865 _update = update
866
866
867 def clean(repo, node, show_stats=True, quietempty=False):
867 def clean(repo, node, show_stats=True, quietempty=False):
868 """forcibly switch the working directory to node, clobbering changes"""
868 """forcibly switch the working directory to node, clobbering changes"""
869 stats = updaterepo(repo, node, True)
869 stats = updaterepo(repo, node, True)
870 repo.vfs.unlinkpath('graftstate', ignoremissing=True)
870 repo.vfs.unlinkpath('graftstate', ignoremissing=True)
871 if show_stats:
871 if show_stats:
872 _showstats(repo, stats, quietempty)
872 _showstats(repo, stats, quietempty)
873 return stats.unresolvedcount > 0
873 return stats.unresolvedcount > 0
874
874
875 # naming conflict in updatetotally()
875 # naming conflict in updatetotally()
876 _clean = clean
876 _clean = clean
877
877
878 def updatetotally(ui, repo, checkout, brev, clean=False, updatecheck=None):
878 def updatetotally(ui, repo, checkout, brev, clean=False, updatecheck=None):
879 """Update the working directory with extra care for non-file components
879 """Update the working directory with extra care for non-file components
880
880
881 This takes care of non-file components below:
881 This takes care of non-file components below:
882
882
883 :bookmark: might be advanced or (in)activated
883 :bookmark: might be advanced or (in)activated
884
884
885 This takes arguments below:
885 This takes arguments below:
886
886
887 :checkout: to which revision the working directory is updated
887 :checkout: to which revision the working directory is updated
888 :brev: a name, which might be a bookmark to be activated after updating
888 :brev: a name, which might be a bookmark to be activated after updating
889 :clean: whether changes in the working directory can be discarded
889 :clean: whether changes in the working directory can be discarded
890 :updatecheck: how to deal with a dirty working directory
890 :updatecheck: how to deal with a dirty working directory
891
891
892 Valid values for updatecheck are (None => linear):
892 Valid values for updatecheck are (None => linear):
893
893
894 * abort: abort if the working directory is dirty
894 * abort: abort if the working directory is dirty
895 * none: don't check (merge working directory changes into destination)
895 * none: don't check (merge working directory changes into destination)
896 * linear: check that update is linear before merging working directory
896 * linear: check that update is linear before merging working directory
897 changes into destination
897 changes into destination
898 * noconflict: check that the update does not result in file merges
898 * noconflict: check that the update does not result in file merges
899
899
900 This returns whether conflict is detected at updating or not.
900 This returns whether conflict is detected at updating or not.
901 """
901 """
902 if updatecheck is None:
902 if updatecheck is None:
903 updatecheck = ui.config('commands', 'update.check')
903 updatecheck = ui.config('commands', 'update.check')
904 if updatecheck not in ('abort', 'none', 'linear', 'noconflict'):
904 if updatecheck not in ('abort', 'none', 'linear', 'noconflict'):
905 # If not configured, or invalid value configured
905 # If not configured, or invalid value configured
906 updatecheck = 'linear'
906 updatecheck = 'linear'
907 with repo.wlock():
907 with repo.wlock():
908 movemarkfrom = None
908 movemarkfrom = None
909 warndest = False
909 warndest = False
910 if checkout is None:
910 if checkout is None:
911 updata = destutil.destupdate(repo, clean=clean)
911 updata = destutil.destupdate(repo, clean=clean)
912 checkout, movemarkfrom, brev = updata
912 checkout, movemarkfrom, brev = updata
913 warndest = True
913 warndest = True
914
914
915 if clean:
915 if clean:
916 ret = _clean(repo, checkout)
916 ret = _clean(repo, checkout)
917 else:
917 else:
918 if updatecheck == 'abort':
918 if updatecheck == 'abort':
919 cmdutil.bailifchanged(repo, merge=False)
919 cmdutil.bailifchanged(repo, merge=False)
920 updatecheck = 'none'
920 updatecheck = 'none'
921 ret = _update(repo, checkout, updatecheck=updatecheck)
921 ret = _update(repo, checkout, updatecheck=updatecheck)
922
922
923 if not ret and movemarkfrom:
923 if not ret and movemarkfrom:
924 if movemarkfrom == repo['.'].node():
924 if movemarkfrom == repo['.'].node():
925 pass # no-op update
925 pass # no-op update
926 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
926 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
927 b = ui.label(repo._activebookmark, 'bookmarks.active')
927 b = ui.label(repo._activebookmark, 'bookmarks.active')
928 ui.status(_("updating bookmark %s\n") % b)
928 ui.status(_("updating bookmark %s\n") % b)
929 else:
929 else:
930 # this can happen with a non-linear update
930 # this can happen with a non-linear update
931 b = ui.label(repo._activebookmark, 'bookmarks')
931 b = ui.label(repo._activebookmark, 'bookmarks')
932 ui.status(_("(leaving bookmark %s)\n") % b)
932 ui.status(_("(leaving bookmark %s)\n") % b)
933 bookmarks.deactivate(repo)
933 bookmarks.deactivate(repo)
934 elif brev in repo._bookmarks:
934 elif brev in repo._bookmarks:
935 if brev != repo._activebookmark:
935 if brev != repo._activebookmark:
936 b = ui.label(brev, 'bookmarks.active')
936 b = ui.label(brev, 'bookmarks.active')
937 ui.status(_("(activating bookmark %s)\n") % b)
937 ui.status(_("(activating bookmark %s)\n") % b)
938 bookmarks.activate(repo, brev)
938 bookmarks.activate(repo, brev)
939 elif brev:
939 elif brev:
940 if repo._activebookmark:
940 if repo._activebookmark:
941 b = ui.label(repo._activebookmark, 'bookmarks')
941 b = ui.label(repo._activebookmark, 'bookmarks')
942 ui.status(_("(leaving bookmark %s)\n") % b)
942 ui.status(_("(leaving bookmark %s)\n") % b)
943 bookmarks.deactivate(repo)
943 bookmarks.deactivate(repo)
944
944
945 if warndest:
945 if warndest:
946 destutil.statusotherdests(ui, repo)
946 destutil.statusotherdests(ui, repo)
947
947
948 return ret
948 return ret
949
949
950 def merge(repo, node, force=None, remind=True, mergeforce=False, labels=None,
950 def merge(repo, node, force=None, remind=True, mergeforce=False, labels=None,
951 abort=False):
951 abort=False):
952 """Branch merge with node, resolving changes. Return true if any
952 """Branch merge with node, resolving changes. Return true if any
953 unresolved conflicts."""
953 unresolved conflicts."""
954 if not abort:
954 if not abort:
955 stats = mergemod.update(repo, node, branchmerge=True, force=force,
955 stats = mergemod.update(repo, node, branchmerge=True, force=force,
956 mergeforce=mergeforce, labels=labels)
956 mergeforce=mergeforce, labels=labels)
957 else:
957 else:
958 ms = mergemod.mergestate.read(repo)
958 ms = mergemod.mergestate.read(repo)
959 if ms.active():
959 if ms.active():
960 # there were conflicts
960 # there were conflicts
961 node = ms.localctx.hex()
961 node = ms.localctx.hex()
962 else:
962 else:
963 # there were no conficts, mergestate was not stored
963 # there were no conficts, mergestate was not stored
964 node = repo['.'].hex()
964 node = repo['.'].hex()
965
965
966 repo.ui.status(_("aborting the merge, updating back to"
966 repo.ui.status(_("aborting the merge, updating back to"
967 " %s\n") % node[:12])
967 " %s\n") % node[:12])
968 stats = mergemod.update(repo, node, branchmerge=False, force=True,
968 stats = mergemod.update(repo, node, branchmerge=False, force=True,
969 labels=labels)
969 labels=labels)
970
970
971 _showstats(repo, stats)
971 _showstats(repo, stats)
972 if stats.unresolvedcount:
972 if stats.unresolvedcount:
973 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
973 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
974 "or 'hg merge --abort' to abandon\n"))
974 "or 'hg merge --abort' to abandon\n"))
975 elif remind and not abort:
975 elif remind and not abort:
976 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
976 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
977 return stats.unresolvedcount > 0
977 return stats.unresolvedcount > 0
978
978
979 def _incoming(displaychlist, subreporecurse, ui, repo, source,
979 def _incoming(displaychlist, subreporecurse, ui, repo, source,
980 opts, buffered=False):
980 opts, buffered=False):
981 """
981 """
982 Helper for incoming / gincoming.
982 Helper for incoming / gincoming.
983 displaychlist gets called with
983 displaychlist gets called with
984 (remoterepo, incomingchangesetlist, displayer) parameters,
984 (remoterepo, incomingchangesetlist, displayer) parameters,
985 and is supposed to contain only code that can't be unified.
985 and is supposed to contain only code that can't be unified.
986 """
986 """
987 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
987 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
988 other = peer(repo, opts, source)
988 other = peer(repo, opts, source)
989 ui.status(_('comparing with %s\n') % util.hidepassword(source))
989 ui.status(_('comparing with %s\n') % util.hidepassword(source))
990 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
990 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
991
991
992 if revs:
992 if revs:
993 revs = [other.lookup(rev) for rev in revs]
993 revs = [other.lookup(rev) for rev in revs]
994 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
994 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
995 revs, opts["bundle"], opts["force"])
995 revs, opts["bundle"], opts["force"])
996 try:
996 try:
997 if not chlist:
997 if not chlist:
998 ui.status(_("no changes found\n"))
998 ui.status(_("no changes found\n"))
999 return subreporecurse()
999 return subreporecurse()
1000 ui.pager('incoming')
1000 ui.pager('incoming')
1001 displayer = logcmdutil.changesetdisplayer(ui, other, opts,
1001 displayer = logcmdutil.changesetdisplayer(ui, other, opts,
1002 buffered=buffered)
1002 buffered=buffered)
1003 displaychlist(other, chlist, displayer)
1003 displaychlist(other, chlist, displayer)
1004 displayer.close()
1004 displayer.close()
1005 finally:
1005 finally:
1006 cleanupfn()
1006 cleanupfn()
1007 subreporecurse()
1007 subreporecurse()
1008 return 0 # exit code is zero since we found incoming changes
1008 return 0 # exit code is zero since we found incoming changes
1009
1009
1010 def incoming(ui, repo, source, opts):
1010 def incoming(ui, repo, source, opts):
1011 def subreporecurse():
1011 def subreporecurse():
1012 ret = 1
1012 ret = 1
1013 if opts.get('subrepos'):
1013 if opts.get('subrepos'):
1014 ctx = repo[None]
1014 ctx = repo[None]
1015 for subpath in sorted(ctx.substate):
1015 for subpath in sorted(ctx.substate):
1016 sub = ctx.sub(subpath)
1016 sub = ctx.sub(subpath)
1017 ret = min(ret, sub.incoming(ui, source, opts))
1017 ret = min(ret, sub.incoming(ui, source, opts))
1018 return ret
1018 return ret
1019
1019
1020 def display(other, chlist, displayer):
1020 def display(other, chlist, displayer):
1021 limit = logcmdutil.getlimit(opts)
1021 limit = logcmdutil.getlimit(opts)
1022 if opts.get('newest_first'):
1022 if opts.get('newest_first'):
1023 chlist.reverse()
1023 chlist.reverse()
1024 count = 0
1024 count = 0
1025 for n in chlist:
1025 for n in chlist:
1026 if limit is not None and count >= limit:
1026 if limit is not None and count >= limit:
1027 break
1027 break
1028 parents = [p for p in other.changelog.parents(n) if p != nullid]
1028 parents = [p for p in other.changelog.parents(n) if p != nullid]
1029 if opts.get('no_merges') and len(parents) == 2:
1029 if opts.get('no_merges') and len(parents) == 2:
1030 continue
1030 continue
1031 count += 1
1031 count += 1
1032 displayer.show(other[n])
1032 displayer.show(other[n])
1033 return _incoming(display, subreporecurse, ui, repo, source, opts)
1033 return _incoming(display, subreporecurse, ui, repo, source, opts)
1034
1034
1035 def _outgoing(ui, repo, dest, opts):
1035 def _outgoing(ui, repo, dest, opts):
1036 path = ui.paths.getpath(dest, default=('default-push', 'default'))
1036 path = ui.paths.getpath(dest, default=('default-push', 'default'))
1037 if not path:
1037 if not path:
1038 raise error.Abort(_('default repository not configured!'),
1038 raise error.Abort(_('default repository not configured!'),
1039 hint=_("see 'hg help config.paths'"))
1039 hint=_("see 'hg help config.paths'"))
1040 dest = path.pushloc or path.loc
1040 dest = path.pushloc or path.loc
1041 branches = path.branch, opts.get('branch') or []
1041 branches = path.branch, opts.get('branch') or []
1042
1042
1043 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1043 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1044 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
1044 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
1045 if revs:
1045 if revs:
1046 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
1046 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
1047
1047
1048 other = peer(repo, opts, dest)
1048 other = peer(repo, opts, dest)
1049 outgoing = discovery.findcommonoutgoing(repo, other, revs,
1049 outgoing = discovery.findcommonoutgoing(repo, other, revs,
1050 force=opts.get('force'))
1050 force=opts.get('force'))
1051 o = outgoing.missing
1051 o = outgoing.missing
1052 if not o:
1052 if not o:
1053 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
1053 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
1054 return o, other
1054 return o, other
1055
1055
1056 def outgoing(ui, repo, dest, opts):
1056 def outgoing(ui, repo, dest, opts):
1057 def recurse():
1057 def recurse():
1058 ret = 1
1058 ret = 1
1059 if opts.get('subrepos'):
1059 if opts.get('subrepos'):
1060 ctx = repo[None]
1060 ctx = repo[None]
1061 for subpath in sorted(ctx.substate):
1061 for subpath in sorted(ctx.substate):
1062 sub = ctx.sub(subpath)
1062 sub = ctx.sub(subpath)
1063 ret = min(ret, sub.outgoing(ui, dest, opts))
1063 ret = min(ret, sub.outgoing(ui, dest, opts))
1064 return ret
1064 return ret
1065
1065
1066 limit = logcmdutil.getlimit(opts)
1066 limit = logcmdutil.getlimit(opts)
1067 o, other = _outgoing(ui, repo, dest, opts)
1067 o, other = _outgoing(ui, repo, dest, opts)
1068 if not o:
1068 if not o:
1069 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1069 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1070 return recurse()
1070 return recurse()
1071
1071
1072 if opts.get('newest_first'):
1072 if opts.get('newest_first'):
1073 o.reverse()
1073 o.reverse()
1074 ui.pager('outgoing')
1074 ui.pager('outgoing')
1075 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
1075 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
1076 count = 0
1076 count = 0
1077 for n in o:
1077 for n in o:
1078 if limit is not None and count >= limit:
1078 if limit is not None and count >= limit:
1079 break
1079 break
1080 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1080 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1081 if opts.get('no_merges') and len(parents) == 2:
1081 if opts.get('no_merges') and len(parents) == 2:
1082 continue
1082 continue
1083 count += 1
1083 count += 1
1084 displayer.show(repo[n])
1084 displayer.show(repo[n])
1085 displayer.close()
1085 displayer.close()
1086 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1086 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1087 recurse()
1087 recurse()
1088 return 0 # exit code is zero since we found outgoing changes
1088 return 0 # exit code is zero since we found outgoing changes
1089
1089
1090 def verify(repo):
1090 def verify(repo):
1091 """verify the consistency of a repository"""
1091 """verify the consistency of a repository"""
1092 ret = verifymod.verify(repo)
1092 ret = verifymod.verify(repo)
1093
1093
1094 # Broken subrepo references in hidden csets don't seem worth worrying about,
1094 # Broken subrepo references in hidden csets don't seem worth worrying about,
1095 # since they can't be pushed/pulled, and --hidden can be used if they are a
1095 # since they can't be pushed/pulled, and --hidden can be used if they are a
1096 # concern.
1096 # concern.
1097
1097
1098 # pathto() is needed for -R case
1098 # pathto() is needed for -R case
1099 revs = repo.revs("filelog(%s)",
1099 revs = repo.revs("filelog(%s)",
1100 util.pathto(repo.root, repo.getcwd(), '.hgsubstate'))
1100 util.pathto(repo.root, repo.getcwd(), '.hgsubstate'))
1101
1101
1102 if revs:
1102 if revs:
1103 repo.ui.status(_('checking subrepo links\n'))
1103 repo.ui.status(_('checking subrepo links\n'))
1104 for rev in revs:
1104 for rev in revs:
1105 ctx = repo[rev]
1105 ctx = repo[rev]
1106 try:
1106 try:
1107 for subpath in ctx.substate:
1107 for subpath in ctx.substate:
1108 try:
1108 try:
1109 ret = (ctx.sub(subpath, allowcreate=False).verify()
1109 ret = (ctx.sub(subpath, allowcreate=False).verify()
1110 or ret)
1110 or ret)
1111 except error.RepoError as e:
1111 except error.RepoError as e:
1112 repo.ui.warn(('%d: %s\n') % (rev, e))
1112 repo.ui.warn(('%d: %s\n') % (rev, e))
1113 except Exception:
1113 except Exception:
1114 repo.ui.warn(_('.hgsubstate is corrupt in revision %s\n') %
1114 repo.ui.warn(_('.hgsubstate is corrupt in revision %s\n') %
1115 node.short(ctx.node()))
1115 node.short(ctx.node()))
1116
1116
1117 return ret
1117 return ret
1118
1118
1119 def remoteui(src, opts):
1119 def remoteui(src, opts):
1120 'build a remote ui from ui or repo and opts'
1120 'build a remote ui from ui or repo and opts'
1121 if util.safehasattr(src, 'baseui'): # looks like a repository
1121 if util.safehasattr(src, 'baseui'): # looks like a repository
1122 dst = src.baseui.copy() # drop repo-specific config
1122 dst = src.baseui.copy() # drop repo-specific config
1123 src = src.ui # copy target options from repo
1123 src = src.ui # copy target options from repo
1124 else: # assume it's a global ui object
1124 else: # assume it's a global ui object
1125 dst = src.copy() # keep all global options
1125 dst = src.copy() # keep all global options
1126
1126
1127 # copy ssh-specific options
1127 # copy ssh-specific options
1128 for o in 'ssh', 'remotecmd':
1128 for o in 'ssh', 'remotecmd':
1129 v = opts.get(o) or src.config('ui', o)
1129 v = opts.get(o) or src.config('ui', o)
1130 if v:
1130 if v:
1131 dst.setconfig("ui", o, v, 'copied')
1131 dst.setconfig("ui", o, v, 'copied')
1132
1132
1133 # copy bundle-specific options
1133 # copy bundle-specific options
1134 r = src.config('bundle', 'mainreporoot')
1134 r = src.config('bundle', 'mainreporoot')
1135 if r:
1135 if r:
1136 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
1136 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
1137
1137
1138 # copy selected local settings to the remote ui
1138 # copy selected local settings to the remote ui
1139 for sect in ('auth', 'hostfingerprints', 'hostsecurity', 'http_proxy'):
1139 for sect in ('auth', 'hostfingerprints', 'hostsecurity', 'http_proxy'):
1140 for key, val in src.configitems(sect):
1140 for key, val in src.configitems(sect):
1141 dst.setconfig(sect, key, val, 'copied')
1141 dst.setconfig(sect, key, val, 'copied')
1142 v = src.config('web', 'cacerts')
1142 v = src.config('web', 'cacerts')
1143 if v:
1143 if v:
1144 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
1144 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
1145
1145
1146 return dst
1146 return dst
1147
1147
1148 # Files of interest
1148 # Files of interest
1149 # Used to check if the repository has changed looking at mtime and size of
1149 # Used to check if the repository has changed looking at mtime and size of
1150 # these files.
1150 # these files.
1151 foi = [('spath', '00changelog.i'),
1151 foi = [('spath', '00changelog.i'),
1152 ('spath', 'phaseroots'), # ! phase can change content at the same size
1152 ('spath', 'phaseroots'), # ! phase can change content at the same size
1153 ('spath', 'obsstore'),
1153 ('spath', 'obsstore'),
1154 ('path', 'bookmarks'), # ! bookmark can change content at the same size
1154 ('path', 'bookmarks'), # ! bookmark can change content at the same size
1155 ]
1155 ]
1156
1156
1157 class cachedlocalrepo(object):
1157 class cachedlocalrepo(object):
1158 """Holds a localrepository that can be cached and reused."""
1158 """Holds a localrepository that can be cached and reused."""
1159
1159
1160 def __init__(self, repo):
1160 def __init__(self, repo):
1161 """Create a new cached repo from an existing repo.
1161 """Create a new cached repo from an existing repo.
1162
1162
1163 We assume the passed in repo was recently created. If the
1163 We assume the passed in repo was recently created. If the
1164 repo has changed between when it was created and when it was
1164 repo has changed between when it was created and when it was
1165 turned into a cache, it may not refresh properly.
1165 turned into a cache, it may not refresh properly.
1166 """
1166 """
1167 assert isinstance(repo, localrepo.localrepository)
1167 assert isinstance(repo, localrepo.localrepository)
1168 self._repo = repo
1168 self._repo = repo
1169 self._state, self.mtime = self._repostate()
1169 self._state, self.mtime = self._repostate()
1170 self._filtername = repo.filtername
1170 self._filtername = repo.filtername
1171
1171
1172 def fetch(self):
1172 def fetch(self):
1173 """Refresh (if necessary) and return a repository.
1173 """Refresh (if necessary) and return a repository.
1174
1174
1175 If the cached instance is out of date, it will be recreated
1175 If the cached instance is out of date, it will be recreated
1176 automatically and returned.
1176 automatically and returned.
1177
1177
1178 Returns a tuple of the repo and a boolean indicating whether a new
1178 Returns a tuple of the repo and a boolean indicating whether a new
1179 repo instance was created.
1179 repo instance was created.
1180 """
1180 """
1181 # We compare the mtimes and sizes of some well-known files to
1181 # We compare the mtimes and sizes of some well-known files to
1182 # determine if the repo changed. This is not precise, as mtimes
1182 # determine if the repo changed. This is not precise, as mtimes
1183 # are susceptible to clock skew and imprecise filesystems and
1183 # are susceptible to clock skew and imprecise filesystems and
1184 # file content can change while maintaining the same size.
1184 # file content can change while maintaining the same size.
1185
1185
1186 state, mtime = self._repostate()
1186 state, mtime = self._repostate()
1187 if state == self._state:
1187 if state == self._state:
1188 return self._repo, False
1188 return self._repo, False
1189
1189
1190 repo = repository(self._repo.baseui, self._repo.url())
1190 repo = repository(self._repo.baseui, self._repo.url())
1191 if self._filtername:
1191 if self._filtername:
1192 self._repo = repo.filtered(self._filtername)
1192 self._repo = repo.filtered(self._filtername)
1193 else:
1193 else:
1194 self._repo = repo.unfiltered()
1194 self._repo = repo.unfiltered()
1195 self._state = state
1195 self._state = state
1196 self.mtime = mtime
1196 self.mtime = mtime
1197
1197
1198 return self._repo, True
1198 return self._repo, True
1199
1199
1200 def _repostate(self):
1200 def _repostate(self):
1201 state = []
1201 state = []
1202 maxmtime = -1
1202 maxmtime = -1
1203 for attr, fname in foi:
1203 for attr, fname in foi:
1204 prefix = getattr(self._repo, attr)
1204 prefix = getattr(self._repo, attr)
1205 p = os.path.join(prefix, fname)
1205 p = os.path.join(prefix, fname)
1206 try:
1206 try:
1207 st = os.stat(p)
1207 st = os.stat(p)
1208 except OSError:
1208 except OSError:
1209 st = os.stat(prefix)
1209 st = os.stat(prefix)
1210 state.append((st[stat.ST_MTIME], st.st_size))
1210 state.append((st[stat.ST_MTIME], st.st_size))
1211 maxmtime = max(maxmtime, st[stat.ST_MTIME])
1211 maxmtime = max(maxmtime, st[stat.ST_MTIME])
1212
1212
1213 return tuple(state), maxmtime
1213 return tuple(state), maxmtime
1214
1214
1215 def copy(self):
1215 def copy(self):
1216 """Obtain a copy of this class instance.
1216 """Obtain a copy of this class instance.
1217
1217
1218 A new localrepository instance is obtained. The new instance should be
1218 A new localrepository instance is obtained. The new instance should be
1219 completely independent of the original.
1219 completely independent of the original.
1220 """
1220 """
1221 repo = repository(self._repo.baseui, self._repo.origroot)
1221 repo = repository(self._repo.baseui, self._repo.origroot)
1222 if self._filtername:
1222 if self._filtername:
1223 repo = repo.filtered(self._filtername)
1223 repo = repo.filtered(self._filtername)
1224 else:
1224 else:
1225 repo = repo.unfiltered()
1225 repo = repo.unfiltered()
1226 c = cachedlocalrepo(repo)
1226 c = cachedlocalrepo(repo)
1227 c._state = self._state
1227 c._state = self._state
1228 c.mtime = self.mtime
1228 c.mtime = self.mtime
1229 return c
1229 return c
@@ -1,1296 +1,1296 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 Prepare repo a:
11 Prepare repo a:
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo a > a
15 $ echo a > a
16 $ hg add a
16 $ hg add a
17 $ hg commit -m test
17 $ hg commit -m test
18 $ echo first line > b
18 $ echo first line > b
19 $ hg add b
19 $ hg add b
20
20
21 Create a non-inlined filelog:
21 Create a non-inlined filelog:
22
22
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
25 > cat data1 >> b
25 > cat data1 >> b
26 > hg commit -m test
26 > hg commit -m test
27 > done
27 > done
28
28
29 List files in store/data (should show a 'b.d'):
29 List files in store/data (should show a 'b.d'):
30
30
31 #if reporevlogstore
31 #if reporevlogstore
32 $ for i in .hg/store/data/*; do
32 $ for i in .hg/store/data/*; do
33 > echo $i
33 > echo $i
34 > done
34 > done
35 .hg/store/data/a.i
35 .hg/store/data/a.i
36 .hg/store/data/b.d
36 .hg/store/data/b.d
37 .hg/store/data/b.i
37 .hg/store/data/b.i
38 #endif
38 #endif
39
39
40 Trigger branchcache creation:
40 Trigger branchcache creation:
41
41
42 $ hg branches
42 $ hg branches
43 default 10:a7949464abda
43 default 10:a7949464abda
44 $ ls .hg/cache
44 $ ls .hg/cache
45 branch2-served
45 branch2-served
46 checkisexec (execbit !)
46 checkisexec (execbit !)
47 checklink (symlink !)
47 checklink (symlink !)
48 checklink-target (symlink !)
48 checklink-target (symlink !)
49 checknoexec (execbit !)
49 checknoexec (execbit !)
50 manifestfulltextcache (reporevlogstore !)
50 manifestfulltextcache (reporevlogstore !)
51 rbc-names-v1
51 rbc-names-v1
52 rbc-revs-v1
52 rbc-revs-v1
53
53
54 Default operation:
54 Default operation:
55
55
56 $ hg clone . ../b
56 $ hg clone . ../b
57 updating to branch default
57 updating to branch default
58 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 $ cd ../b
59 $ cd ../b
60
60
61 Ensure branchcache got copied over:
61 Ensure branchcache got copied over:
62
62
63 $ ls .hg/cache
63 $ ls .hg/cache
64 branch2-served
64 branch2-served
65 checkisexec (execbit !)
65 checkisexec (execbit !)
66 checklink (symlink !)
66 checklink (symlink !)
67 checklink-target (symlink !)
67 checklink-target (symlink !)
68 rbc-names-v1
68 rbc-names-v1
69 rbc-revs-v1
69 rbc-revs-v1
70
70
71 $ cat a
71 $ cat a
72 a
72 a
73 $ hg verify
73 $ hg verify
74 checking changesets
74 checking changesets
75 checking manifests
75 checking manifests
76 crosschecking files in changesets and manifests
76 crosschecking files in changesets and manifests
77 checking files
77 checking files
78 checked 11 changesets with 11 changes to 2 files
78 checked 11 changesets with 11 changes to 2 files
79
79
80 Invalid dest '' must abort:
80 Invalid dest '' must abort:
81
81
82 $ hg clone . ''
82 $ hg clone . ''
83 abort: empty destination path is not valid
83 abort: empty destination path is not valid
84 [255]
84 [255]
85
85
86 No update, with debug option:
86 No update, with debug option:
87
87
88 #if hardlink
88 #if hardlink
89 $ hg --debug clone -U . ../c --config progress.debug=true
89 $ hg --debug clone -U . ../c --config progress.debug=true
90 linking: 1
90 linking: 1 files
91 linking: 2
91 linking: 2 files
92 linking: 3
92 linking: 3 files
93 linking: 4
93 linking: 4 files
94 linking: 5
94 linking: 5 files
95 linking: 6
95 linking: 6 files
96 linking: 7
96 linking: 7 files
97 linking: 8
97 linking: 8 files
98 linked 8 files (reporevlogstore !)
98 linked 8 files (reporevlogstore !)
99 linking: 9 (reposimplestore !)
99 linking: 9 files (reposimplestore !)
100 linking: 10 (reposimplestore !)
100 linking: 10 files (reposimplestore !)
101 linking: 11 (reposimplestore !)
101 linking: 11 files (reposimplestore !)
102 linking: 12 (reposimplestore !)
102 linking: 12 files (reposimplestore !)
103 linking: 13 (reposimplestore !)
103 linking: 13 files (reposimplestore !)
104 linking: 14 (reposimplestore !)
104 linking: 14 files (reposimplestore !)
105 linking: 15 (reposimplestore !)
105 linking: 15 files (reposimplestore !)
106 linking: 16 (reposimplestore !)
106 linking: 16 files (reposimplestore !)
107 linking: 17 (reposimplestore !)
107 linking: 17 files (reposimplestore !)
108 linking: 18 (reposimplestore !)
108 linking: 18 files (reposimplestore !)
109 linked 18 files (reposimplestore !)
109 linked 18 files (reposimplestore !)
110 #else
110 #else
111 $ hg --debug clone -U . ../c --config progress.debug=true
111 $ hg --debug clone -U . ../c --config progress.debug=true
112 linking: 1
112 linking: 1 files
113 copying: 2
113 copying: 2 files
114 copying: 3
114 copying: 3 files
115 copying: 4
115 copying: 4 files
116 copying: 5
116 copying: 5 files
117 copying: 6
117 copying: 6 files
118 copying: 7
118 copying: 7 files
119 copying: 8
119 copying: 8 files
120 copied 8 files (reporevlogstore !)
120 copied 8 files (reporevlogstore !)
121 copying: 9 (reposimplestore !)
121 copying: 9 files (reposimplestore !)
122 copying: 10 (reposimplestore !)
122 copying: 10 files (reposimplestore !)
123 copying: 11 (reposimplestore !)
123 copying: 11 files (reposimplestore !)
124 copying: 12 (reposimplestore !)
124 copying: 12 files (reposimplestore !)
125 copying: 13 (reposimplestore !)
125 copying: 13 files (reposimplestore !)
126 copying: 14 (reposimplestore !)
126 copying: 14 files (reposimplestore !)
127 copying: 15 (reposimplestore !)
127 copying: 15 files (reposimplestore !)
128 copying: 16 (reposimplestore !)
128 copying: 16 files (reposimplestore !)
129 copying: 17 (reposimplestore !)
129 copying: 17 files (reposimplestore !)
130 copying: 18 (reposimplestore !)
130 copying: 18 files (reposimplestore !)
131 copied 18 files (reposimplestore !)
131 copied 18 files (reposimplestore !)
132 #endif
132 #endif
133 $ cd ../c
133 $ cd ../c
134
134
135 Ensure branchcache got copied over:
135 Ensure branchcache got copied over:
136
136
137 $ ls .hg/cache
137 $ ls .hg/cache
138 branch2-served
138 branch2-served
139 rbc-names-v1
139 rbc-names-v1
140 rbc-revs-v1
140 rbc-revs-v1
141
141
142 $ cat a 2>/dev/null || echo "a not present"
142 $ cat a 2>/dev/null || echo "a not present"
143 a not present
143 a not present
144 $ hg verify
144 $ hg verify
145 checking changesets
145 checking changesets
146 checking manifests
146 checking manifests
147 crosschecking files in changesets and manifests
147 crosschecking files in changesets and manifests
148 checking files
148 checking files
149 checked 11 changesets with 11 changes to 2 files
149 checked 11 changesets with 11 changes to 2 files
150
150
151 Default destination:
151 Default destination:
152
152
153 $ mkdir ../d
153 $ mkdir ../d
154 $ cd ../d
154 $ cd ../d
155 $ hg clone ../a
155 $ hg clone ../a
156 destination directory: a
156 destination directory: a
157 updating to branch default
157 updating to branch default
158 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 $ cd a
159 $ cd a
160 $ hg cat a
160 $ hg cat a
161 a
161 a
162 $ cd ../..
162 $ cd ../..
163
163
164 Check that we drop the 'file:' from the path before writing the .hgrc:
164 Check that we drop the 'file:' from the path before writing the .hgrc:
165
165
166 $ hg clone file:a e
166 $ hg clone file:a e
167 updating to branch default
167 updating to branch default
168 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 $ grep 'file:' e/.hg/hgrc
169 $ grep 'file:' e/.hg/hgrc
170 [1]
170 [1]
171
171
172 Check that path aliases are expanded:
172 Check that path aliases are expanded:
173
173
174 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
174 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
175 $ hg -R f showconfig paths.default
175 $ hg -R f showconfig paths.default
176 $TESTTMP/a#0
176 $TESTTMP/a#0
177
177
178 Use --pull:
178 Use --pull:
179
179
180 $ hg clone --pull a g
180 $ hg clone --pull a g
181 requesting all changes
181 requesting all changes
182 adding changesets
182 adding changesets
183 adding manifests
183 adding manifests
184 adding file changes
184 adding file changes
185 added 11 changesets with 11 changes to 2 files
185 added 11 changesets with 11 changes to 2 files
186 new changesets acb14030fe0a:a7949464abda
186 new changesets acb14030fe0a:a7949464abda
187 updating to branch default
187 updating to branch default
188 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
188 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
189 $ hg -R g verify
189 $ hg -R g verify
190 checking changesets
190 checking changesets
191 checking manifests
191 checking manifests
192 crosschecking files in changesets and manifests
192 crosschecking files in changesets and manifests
193 checking files
193 checking files
194 checked 11 changesets with 11 changes to 2 files
194 checked 11 changesets with 11 changes to 2 files
195
195
196 Invalid dest '' with --pull must abort (issue2528):
196 Invalid dest '' with --pull must abort (issue2528):
197
197
198 $ hg clone --pull a ''
198 $ hg clone --pull a ''
199 abort: empty destination path is not valid
199 abort: empty destination path is not valid
200 [255]
200 [255]
201
201
202 Clone to '.':
202 Clone to '.':
203
203
204 $ mkdir h
204 $ mkdir h
205 $ cd h
205 $ cd h
206 $ hg clone ../a .
206 $ hg clone ../a .
207 updating to branch default
207 updating to branch default
208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
209 $ cd ..
209 $ cd ..
210
210
211
211
212 *** Tests for option -u ***
212 *** Tests for option -u ***
213
213
214 Adding some more history to repo a:
214 Adding some more history to repo a:
215
215
216 $ cd a
216 $ cd a
217 $ hg tag ref1
217 $ hg tag ref1
218 $ echo the quick brown fox >a
218 $ echo the quick brown fox >a
219 $ hg ci -m "hacked default"
219 $ hg ci -m "hacked default"
220 $ hg up ref1
220 $ hg up ref1
221 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
221 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
222 $ hg branch stable
222 $ hg branch stable
223 marked working directory as branch stable
223 marked working directory as branch stable
224 (branches are permanent and global, did you want a bookmark?)
224 (branches are permanent and global, did you want a bookmark?)
225 $ echo some text >a
225 $ echo some text >a
226 $ hg ci -m "starting branch stable"
226 $ hg ci -m "starting branch stable"
227 $ hg tag ref2
227 $ hg tag ref2
228 $ echo some more text >a
228 $ echo some more text >a
229 $ hg ci -m "another change for branch stable"
229 $ hg ci -m "another change for branch stable"
230 $ hg up ref2
230 $ hg up ref2
231 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
231 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
232 $ hg parents
232 $ hg parents
233 changeset: 13:e8ece76546a6
233 changeset: 13:e8ece76546a6
234 branch: stable
234 branch: stable
235 tag: ref2
235 tag: ref2
236 parent: 10:a7949464abda
236 parent: 10:a7949464abda
237 user: test
237 user: test
238 date: Thu Jan 01 00:00:00 1970 +0000
238 date: Thu Jan 01 00:00:00 1970 +0000
239 summary: starting branch stable
239 summary: starting branch stable
240
240
241
241
242 Repo a has two heads:
242 Repo a has two heads:
243
243
244 $ hg heads
244 $ hg heads
245 changeset: 15:0aae7cf88f0d
245 changeset: 15:0aae7cf88f0d
246 branch: stable
246 branch: stable
247 tag: tip
247 tag: tip
248 user: test
248 user: test
249 date: Thu Jan 01 00:00:00 1970 +0000
249 date: Thu Jan 01 00:00:00 1970 +0000
250 summary: another change for branch stable
250 summary: another change for branch stable
251
251
252 changeset: 12:f21241060d6a
252 changeset: 12:f21241060d6a
253 user: test
253 user: test
254 date: Thu Jan 01 00:00:00 1970 +0000
254 date: Thu Jan 01 00:00:00 1970 +0000
255 summary: hacked default
255 summary: hacked default
256
256
257
257
258 $ cd ..
258 $ cd ..
259
259
260
260
261 Testing --noupdate with --updaterev (must abort):
261 Testing --noupdate with --updaterev (must abort):
262
262
263 $ hg clone --noupdate --updaterev 1 a ua
263 $ hg clone --noupdate --updaterev 1 a ua
264 abort: cannot specify both --noupdate and --updaterev
264 abort: cannot specify both --noupdate and --updaterev
265 [255]
265 [255]
266
266
267
267
268 Testing clone -u:
268 Testing clone -u:
269
269
270 $ hg clone -u . a ua
270 $ hg clone -u . a ua
271 updating to branch stable
271 updating to branch stable
272 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
273
273
274 Repo ua has both heads:
274 Repo ua has both heads:
275
275
276 $ hg -R ua heads
276 $ hg -R ua heads
277 changeset: 15:0aae7cf88f0d
277 changeset: 15:0aae7cf88f0d
278 branch: stable
278 branch: stable
279 tag: tip
279 tag: tip
280 user: test
280 user: test
281 date: Thu Jan 01 00:00:00 1970 +0000
281 date: Thu Jan 01 00:00:00 1970 +0000
282 summary: another change for branch stable
282 summary: another change for branch stable
283
283
284 changeset: 12:f21241060d6a
284 changeset: 12:f21241060d6a
285 user: test
285 user: test
286 date: Thu Jan 01 00:00:00 1970 +0000
286 date: Thu Jan 01 00:00:00 1970 +0000
287 summary: hacked default
287 summary: hacked default
288
288
289
289
290 Same revision checked out in repo a and ua:
290 Same revision checked out in repo a and ua:
291
291
292 $ hg -R a parents --template "{node|short}\n"
292 $ hg -R a parents --template "{node|short}\n"
293 e8ece76546a6
293 e8ece76546a6
294 $ hg -R ua parents --template "{node|short}\n"
294 $ hg -R ua parents --template "{node|short}\n"
295 e8ece76546a6
295 e8ece76546a6
296
296
297 $ rm -r ua
297 $ rm -r ua
298
298
299
299
300 Testing clone --pull -u:
300 Testing clone --pull -u:
301
301
302 $ hg clone --pull -u . a ua
302 $ hg clone --pull -u . a ua
303 requesting all changes
303 requesting all changes
304 adding changesets
304 adding changesets
305 adding manifests
305 adding manifests
306 adding file changes
306 adding file changes
307 added 16 changesets with 16 changes to 3 files (+1 heads)
307 added 16 changesets with 16 changes to 3 files (+1 heads)
308 new changesets acb14030fe0a:0aae7cf88f0d
308 new changesets acb14030fe0a:0aae7cf88f0d
309 updating to branch stable
309 updating to branch stable
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
311
311
312 Repo ua has both heads:
312 Repo ua has both heads:
313
313
314 $ hg -R ua heads
314 $ hg -R ua heads
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 changeset: 12:f21241060d6a
322 changeset: 12:f21241060d6a
323 user: test
323 user: test
324 date: Thu Jan 01 00:00:00 1970 +0000
324 date: Thu Jan 01 00:00:00 1970 +0000
325 summary: hacked default
325 summary: hacked default
326
326
327
327
328 Same revision checked out in repo a and ua:
328 Same revision checked out in repo a and ua:
329
329
330 $ hg -R a parents --template "{node|short}\n"
330 $ hg -R a parents --template "{node|short}\n"
331 e8ece76546a6
331 e8ece76546a6
332 $ hg -R ua parents --template "{node|short}\n"
332 $ hg -R ua parents --template "{node|short}\n"
333 e8ece76546a6
333 e8ece76546a6
334
334
335 $ rm -r ua
335 $ rm -r ua
336
336
337
337
338 Testing clone -u <branch>:
338 Testing clone -u <branch>:
339
339
340 $ hg clone -u stable a ua
340 $ hg clone -u stable a ua
341 updating to branch stable
341 updating to branch stable
342 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
343
343
344 Repo ua has both heads:
344 Repo ua has both heads:
345
345
346 $ hg -R ua heads
346 $ hg -R ua heads
347 changeset: 15:0aae7cf88f0d
347 changeset: 15:0aae7cf88f0d
348 branch: stable
348 branch: stable
349 tag: tip
349 tag: tip
350 user: test
350 user: test
351 date: Thu Jan 01 00:00:00 1970 +0000
351 date: Thu Jan 01 00:00:00 1970 +0000
352 summary: another change for branch stable
352 summary: another change for branch stable
353
353
354 changeset: 12:f21241060d6a
354 changeset: 12:f21241060d6a
355 user: test
355 user: test
356 date: Thu Jan 01 00:00:00 1970 +0000
356 date: Thu Jan 01 00:00:00 1970 +0000
357 summary: hacked default
357 summary: hacked default
358
358
359
359
360 Branch 'stable' is checked out:
360 Branch 'stable' is checked out:
361
361
362 $ hg -R ua parents
362 $ hg -R ua parents
363 changeset: 15:0aae7cf88f0d
363 changeset: 15:0aae7cf88f0d
364 branch: stable
364 branch: stable
365 tag: tip
365 tag: tip
366 user: test
366 user: test
367 date: Thu Jan 01 00:00:00 1970 +0000
367 date: Thu Jan 01 00:00:00 1970 +0000
368 summary: another change for branch stable
368 summary: another change for branch stable
369
369
370
370
371 $ rm -r ua
371 $ rm -r ua
372
372
373
373
374 Testing default checkout:
374 Testing default checkout:
375
375
376 $ hg clone a ua
376 $ hg clone a ua
377 updating to branch default
377 updating to branch default
378 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
379
379
380 Repo ua has both heads:
380 Repo ua has both heads:
381
381
382 $ hg -R ua heads
382 $ hg -R ua heads
383 changeset: 15:0aae7cf88f0d
383 changeset: 15:0aae7cf88f0d
384 branch: stable
384 branch: stable
385 tag: tip
385 tag: tip
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: another change for branch stable
388 summary: another change for branch stable
389
389
390 changeset: 12:f21241060d6a
390 changeset: 12:f21241060d6a
391 user: test
391 user: test
392 date: Thu Jan 01 00:00:00 1970 +0000
392 date: Thu Jan 01 00:00:00 1970 +0000
393 summary: hacked default
393 summary: hacked default
394
394
395
395
396 Branch 'default' is checked out:
396 Branch 'default' is checked out:
397
397
398 $ hg -R ua parents
398 $ hg -R ua parents
399 changeset: 12:f21241060d6a
399 changeset: 12:f21241060d6a
400 user: test
400 user: test
401 date: Thu Jan 01 00:00:00 1970 +0000
401 date: Thu Jan 01 00:00:00 1970 +0000
402 summary: hacked default
402 summary: hacked default
403
403
404 Test clone with a branch named "@" (issue3677)
404 Test clone with a branch named "@" (issue3677)
405
405
406 $ hg -R ua branch @
406 $ hg -R ua branch @
407 marked working directory as branch @
407 marked working directory as branch @
408 $ hg -R ua commit -m 'created branch @'
408 $ hg -R ua commit -m 'created branch @'
409 $ hg clone ua atbranch
409 $ hg clone ua atbranch
410 updating to branch default
410 updating to branch default
411 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
411 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
412 $ hg -R atbranch heads
412 $ hg -R atbranch heads
413 changeset: 16:798b6d97153e
413 changeset: 16:798b6d97153e
414 branch: @
414 branch: @
415 tag: tip
415 tag: tip
416 parent: 12:f21241060d6a
416 parent: 12:f21241060d6a
417 user: test
417 user: test
418 date: Thu Jan 01 00:00:00 1970 +0000
418 date: Thu Jan 01 00:00:00 1970 +0000
419 summary: created branch @
419 summary: created branch @
420
420
421 changeset: 15:0aae7cf88f0d
421 changeset: 15:0aae7cf88f0d
422 branch: stable
422 branch: stable
423 user: test
423 user: test
424 date: Thu Jan 01 00:00:00 1970 +0000
424 date: Thu Jan 01 00:00:00 1970 +0000
425 summary: another change for branch stable
425 summary: another change for branch stable
426
426
427 changeset: 12:f21241060d6a
427 changeset: 12:f21241060d6a
428 user: test
428 user: test
429 date: Thu Jan 01 00:00:00 1970 +0000
429 date: Thu Jan 01 00:00:00 1970 +0000
430 summary: hacked default
430 summary: hacked default
431
431
432 $ hg -R atbranch parents
432 $ hg -R atbranch parents
433 changeset: 12:f21241060d6a
433 changeset: 12:f21241060d6a
434 user: test
434 user: test
435 date: Thu Jan 01 00:00:00 1970 +0000
435 date: Thu Jan 01 00:00:00 1970 +0000
436 summary: hacked default
436 summary: hacked default
437
437
438
438
439 $ rm -r ua atbranch
439 $ rm -r ua atbranch
440
440
441
441
442 Testing #<branch>:
442 Testing #<branch>:
443
443
444 $ hg clone -u . a#stable ua
444 $ hg clone -u . a#stable ua
445 adding changesets
445 adding changesets
446 adding manifests
446 adding manifests
447 adding file changes
447 adding file changes
448 added 14 changesets with 14 changes to 3 files
448 added 14 changesets with 14 changes to 3 files
449 new changesets acb14030fe0a:0aae7cf88f0d
449 new changesets acb14030fe0a:0aae7cf88f0d
450 updating to branch stable
450 updating to branch stable
451 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
451 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
452
452
453 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
453 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
454
454
455 $ hg -R ua heads
455 $ hg -R ua heads
456 changeset: 13:0aae7cf88f0d
456 changeset: 13:0aae7cf88f0d
457 branch: stable
457 branch: stable
458 tag: tip
458 tag: tip
459 user: test
459 user: test
460 date: Thu Jan 01 00:00:00 1970 +0000
460 date: Thu Jan 01 00:00:00 1970 +0000
461 summary: another change for branch stable
461 summary: another change for branch stable
462
462
463 changeset: 10:a7949464abda
463 changeset: 10:a7949464abda
464 user: test
464 user: test
465 date: Thu Jan 01 00:00:00 1970 +0000
465 date: Thu Jan 01 00:00:00 1970 +0000
466 summary: test
466 summary: test
467
467
468
468
469 Same revision checked out in repo a and ua:
469 Same revision checked out in repo a and ua:
470
470
471 $ hg -R a parents --template "{node|short}\n"
471 $ hg -R a parents --template "{node|short}\n"
472 e8ece76546a6
472 e8ece76546a6
473 $ hg -R ua parents --template "{node|short}\n"
473 $ hg -R ua parents --template "{node|short}\n"
474 e8ece76546a6
474 e8ece76546a6
475
475
476 $ rm -r ua
476 $ rm -r ua
477
477
478
478
479 Testing -u -r <branch>:
479 Testing -u -r <branch>:
480
480
481 $ hg clone -u . -r stable a ua
481 $ hg clone -u . -r stable a ua
482 adding changesets
482 adding changesets
483 adding manifests
483 adding manifests
484 adding file changes
484 adding file changes
485 added 14 changesets with 14 changes to 3 files
485 added 14 changesets with 14 changes to 3 files
486 new changesets acb14030fe0a:0aae7cf88f0d
486 new changesets acb14030fe0a:0aae7cf88f0d
487 updating to branch stable
487 updating to branch stable
488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
489
489
490 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
490 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
491
491
492 $ hg -R ua heads
492 $ hg -R ua heads
493 changeset: 13:0aae7cf88f0d
493 changeset: 13:0aae7cf88f0d
494 branch: stable
494 branch: stable
495 tag: tip
495 tag: tip
496 user: test
496 user: test
497 date: Thu Jan 01 00:00:00 1970 +0000
497 date: Thu Jan 01 00:00:00 1970 +0000
498 summary: another change for branch stable
498 summary: another change for branch stable
499
499
500 changeset: 10:a7949464abda
500 changeset: 10:a7949464abda
501 user: test
501 user: test
502 date: Thu Jan 01 00:00:00 1970 +0000
502 date: Thu Jan 01 00:00:00 1970 +0000
503 summary: test
503 summary: test
504
504
505
505
506 Same revision checked out in repo a and ua:
506 Same revision checked out in repo a and ua:
507
507
508 $ hg -R a parents --template "{node|short}\n"
508 $ hg -R a parents --template "{node|short}\n"
509 e8ece76546a6
509 e8ece76546a6
510 $ hg -R ua parents --template "{node|short}\n"
510 $ hg -R ua parents --template "{node|short}\n"
511 e8ece76546a6
511 e8ece76546a6
512
512
513 $ rm -r ua
513 $ rm -r ua
514
514
515
515
516 Testing -r <branch>:
516 Testing -r <branch>:
517
517
518 $ hg clone -r stable a ua
518 $ hg clone -r stable a ua
519 adding changesets
519 adding changesets
520 adding manifests
520 adding manifests
521 adding file changes
521 adding file changes
522 added 14 changesets with 14 changes to 3 files
522 added 14 changesets with 14 changes to 3 files
523 new changesets acb14030fe0a:0aae7cf88f0d
523 new changesets acb14030fe0a:0aae7cf88f0d
524 updating to branch stable
524 updating to branch stable
525 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
526
526
527 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
527 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
528
528
529 $ hg -R ua heads
529 $ hg -R ua heads
530 changeset: 13:0aae7cf88f0d
530 changeset: 13:0aae7cf88f0d
531 branch: stable
531 branch: stable
532 tag: tip
532 tag: tip
533 user: test
533 user: test
534 date: Thu Jan 01 00:00:00 1970 +0000
534 date: Thu Jan 01 00:00:00 1970 +0000
535 summary: another change for branch stable
535 summary: another change for branch stable
536
536
537 changeset: 10:a7949464abda
537 changeset: 10:a7949464abda
538 user: test
538 user: test
539 date: Thu Jan 01 00:00:00 1970 +0000
539 date: Thu Jan 01 00:00:00 1970 +0000
540 summary: test
540 summary: test
541
541
542
542
543 Branch 'stable' is checked out:
543 Branch 'stable' is checked out:
544
544
545 $ hg -R ua parents
545 $ hg -R ua parents
546 changeset: 13:0aae7cf88f0d
546 changeset: 13:0aae7cf88f0d
547 branch: stable
547 branch: stable
548 tag: tip
548 tag: tip
549 user: test
549 user: test
550 date: Thu Jan 01 00:00:00 1970 +0000
550 date: Thu Jan 01 00:00:00 1970 +0000
551 summary: another change for branch stable
551 summary: another change for branch stable
552
552
553
553
554 $ rm -r ua
554 $ rm -r ua
555
555
556
556
557 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
557 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
558 iterable in addbranchrevs()
558 iterable in addbranchrevs()
559
559
560 $ cat <<EOF > simpleclone.py
560 $ cat <<EOF > simpleclone.py
561 > from mercurial import hg, ui as uimod
561 > from mercurial import hg, ui as uimod
562 > myui = uimod.ui.load()
562 > myui = uimod.ui.load()
563 > repo = hg.repository(myui, b'a')
563 > repo = hg.repository(myui, b'a')
564 > hg.clone(myui, {}, repo, dest=b"ua")
564 > hg.clone(myui, {}, repo, dest=b"ua")
565 > EOF
565 > EOF
566
566
567 $ "$PYTHON" simpleclone.py
567 $ "$PYTHON" simpleclone.py
568 updating to branch default
568 updating to branch default
569 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
569 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
570
570
571 $ rm -r ua
571 $ rm -r ua
572
572
573 $ cat <<EOF > branchclone.py
573 $ cat <<EOF > branchclone.py
574 > from mercurial import extensions, hg, ui as uimod
574 > from mercurial import extensions, hg, ui as uimod
575 > myui = uimod.ui.load()
575 > myui = uimod.ui.load()
576 > extensions.loadall(myui)
576 > extensions.loadall(myui)
577 > repo = hg.repository(myui, b'a')
577 > repo = hg.repository(myui, b'a')
578 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable",])
578 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable",])
579 > EOF
579 > EOF
580
580
581 $ "$PYTHON" branchclone.py
581 $ "$PYTHON" branchclone.py
582 adding changesets
582 adding changesets
583 adding manifests
583 adding manifests
584 adding file changes
584 adding file changes
585 added 14 changesets with 14 changes to 3 files
585 added 14 changesets with 14 changes to 3 files
586 new changesets acb14030fe0a:0aae7cf88f0d
586 new changesets acb14030fe0a:0aae7cf88f0d
587 updating to branch stable
587 updating to branch stable
588 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
589 $ rm -r ua
589 $ rm -r ua
590
590
591
591
592 Test clone with special '@' bookmark:
592 Test clone with special '@' bookmark:
593 $ cd a
593 $ cd a
594 $ hg bookmark -r a7949464abda @ # branch point of stable from default
594 $ hg bookmark -r a7949464abda @ # branch point of stable from default
595 $ hg clone . ../i
595 $ hg clone . ../i
596 updating to bookmark @
596 updating to bookmark @
597 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
597 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
598 $ hg id -i ../i
598 $ hg id -i ../i
599 a7949464abda
599 a7949464abda
600 $ rm -r ../i
600 $ rm -r ../i
601
601
602 $ hg bookmark -f -r stable @
602 $ hg bookmark -f -r stable @
603 $ hg bookmarks
603 $ hg bookmarks
604 @ 15:0aae7cf88f0d
604 @ 15:0aae7cf88f0d
605 $ hg clone . ../i
605 $ hg clone . ../i
606 updating to bookmark @ on branch stable
606 updating to bookmark @ on branch stable
607 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
607 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
608 $ hg id -i ../i
608 $ hg id -i ../i
609 0aae7cf88f0d
609 0aae7cf88f0d
610 $ cd "$TESTTMP"
610 $ cd "$TESTTMP"
611
611
612
612
613 Testing failures:
613 Testing failures:
614
614
615 $ mkdir fail
615 $ mkdir fail
616 $ cd fail
616 $ cd fail
617
617
618 No local source
618 No local source
619
619
620 $ hg clone a b
620 $ hg clone a b
621 abort: repository a not found!
621 abort: repository a not found!
622 [255]
622 [255]
623
623
624 No remote source
624 No remote source
625
625
626 #if windows
626 #if windows
627 $ hg clone http://$LOCALIP:3121/a b
627 $ hg clone http://$LOCALIP:3121/a b
628 abort: error: * (glob)
628 abort: error: * (glob)
629 [255]
629 [255]
630 #else
630 #else
631 $ hg clone http://$LOCALIP:3121/a b
631 $ hg clone http://$LOCALIP:3121/a b
632 abort: error: *refused* (glob)
632 abort: error: *refused* (glob)
633 [255]
633 [255]
634 #endif
634 #endif
635 $ rm -rf b # work around bug with http clone
635 $ rm -rf b # work around bug with http clone
636
636
637
637
638 #if unix-permissions no-root
638 #if unix-permissions no-root
639
639
640 Inaccessible source
640 Inaccessible source
641
641
642 $ mkdir a
642 $ mkdir a
643 $ chmod 000 a
643 $ chmod 000 a
644 $ hg clone a b
644 $ hg clone a b
645 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
645 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
646 [255]
646 [255]
647
647
648 Inaccessible destination
648 Inaccessible destination
649
649
650 $ hg init b
650 $ hg init b
651 $ cd b
651 $ cd b
652 $ hg clone . ../a
652 $ hg clone . ../a
653 abort: Permission denied: *../a* (glob)
653 abort: Permission denied: *../a* (glob)
654 [255]
654 [255]
655 $ cd ..
655 $ cd ..
656 $ chmod 700 a
656 $ chmod 700 a
657 $ rm -r a b
657 $ rm -r a b
658
658
659 #endif
659 #endif
660
660
661
661
662 #if fifo
662 #if fifo
663
663
664 Source of wrong type
664 Source of wrong type
665
665
666 $ mkfifo a
666 $ mkfifo a
667 $ hg clone a b
667 $ hg clone a b
668 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
668 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
669 [255]
669 [255]
670 $ rm a
670 $ rm a
671
671
672 #endif
672 #endif
673
673
674 Default destination, same directory
674 Default destination, same directory
675
675
676 $ hg init q
676 $ hg init q
677 $ hg clone q
677 $ hg clone q
678 destination directory: q
678 destination directory: q
679 abort: destination 'q' is not empty
679 abort: destination 'q' is not empty
680 [255]
680 [255]
681
681
682 destination directory not empty
682 destination directory not empty
683
683
684 $ mkdir a
684 $ mkdir a
685 $ echo stuff > a/a
685 $ echo stuff > a/a
686 $ hg clone q a
686 $ hg clone q a
687 abort: destination 'a' is not empty
687 abort: destination 'a' is not empty
688 [255]
688 [255]
689
689
690
690
691 #if unix-permissions no-root
691 #if unix-permissions no-root
692
692
693 leave existing directory in place after clone failure
693 leave existing directory in place after clone failure
694
694
695 $ hg init c
695 $ hg init c
696 $ cd c
696 $ cd c
697 $ echo c > c
697 $ echo c > c
698 $ hg commit -A -m test
698 $ hg commit -A -m test
699 adding c
699 adding c
700 $ chmod -rx .hg/store/data
700 $ chmod -rx .hg/store/data
701 $ cd ..
701 $ cd ..
702 $ mkdir d
702 $ mkdir d
703 $ hg clone c d 2> err
703 $ hg clone c d 2> err
704 [255]
704 [255]
705 $ test -d d
705 $ test -d d
706 $ test -d d/.hg
706 $ test -d d/.hg
707 [1]
707 [1]
708
708
709 re-enable perm to allow deletion
709 re-enable perm to allow deletion
710
710
711 $ chmod +rx c/.hg/store/data
711 $ chmod +rx c/.hg/store/data
712
712
713 #endif
713 #endif
714
714
715 $ cd ..
715 $ cd ..
716
716
717 Test clone from the repository in (emulated) revlog format 0 (issue4203):
717 Test clone from the repository in (emulated) revlog format 0 (issue4203):
718
718
719 $ mkdir issue4203
719 $ mkdir issue4203
720 $ mkdir -p src/.hg
720 $ mkdir -p src/.hg
721 $ echo foo > src/foo
721 $ echo foo > src/foo
722 $ hg -R src add src/foo
722 $ hg -R src add src/foo
723 $ hg -R src commit -m '#0'
723 $ hg -R src commit -m '#0'
724 $ hg -R src log -q
724 $ hg -R src log -q
725 0:e1bab28bca43
725 0:e1bab28bca43
726 $ hg clone -U -q src dst
726 $ hg clone -U -q src dst
727 $ hg -R dst log -q
727 $ hg -R dst log -q
728 0:e1bab28bca43
728 0:e1bab28bca43
729
729
730 Create repositories to test auto sharing functionality
730 Create repositories to test auto sharing functionality
731
731
732 $ cat >> $HGRCPATH << EOF
732 $ cat >> $HGRCPATH << EOF
733 > [extensions]
733 > [extensions]
734 > share=
734 > share=
735 > EOF
735 > EOF
736
736
737 $ hg init empty
737 $ hg init empty
738 $ hg init source1a
738 $ hg init source1a
739 $ cd source1a
739 $ cd source1a
740 $ echo initial1 > foo
740 $ echo initial1 > foo
741 $ hg -q commit -A -m initial
741 $ hg -q commit -A -m initial
742 $ echo second > foo
742 $ echo second > foo
743 $ hg commit -m second
743 $ hg commit -m second
744 $ cd ..
744 $ cd ..
745
745
746 $ hg init filteredrev0
746 $ hg init filteredrev0
747 $ cd filteredrev0
747 $ cd filteredrev0
748 $ cat >> .hg/hgrc << EOF
748 $ cat >> .hg/hgrc << EOF
749 > [experimental]
749 > [experimental]
750 > evolution.createmarkers=True
750 > evolution.createmarkers=True
751 > EOF
751 > EOF
752 $ echo initial1 > foo
752 $ echo initial1 > foo
753 $ hg -q commit -A -m initial0
753 $ hg -q commit -A -m initial0
754 $ hg -q up -r null
754 $ hg -q up -r null
755 $ echo initial2 > foo
755 $ echo initial2 > foo
756 $ hg -q commit -A -m initial1
756 $ hg -q commit -A -m initial1
757 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
757 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
758 obsoleted 1 changesets
758 obsoleted 1 changesets
759 $ cd ..
759 $ cd ..
760
760
761 $ hg -q clone --pull source1a source1b
761 $ hg -q clone --pull source1a source1b
762 $ cd source1a
762 $ cd source1a
763 $ hg bookmark bookA
763 $ hg bookmark bookA
764 $ echo 1a > foo
764 $ echo 1a > foo
765 $ hg commit -m 1a
765 $ hg commit -m 1a
766 $ cd ../source1b
766 $ cd ../source1b
767 $ hg -q up -r 0
767 $ hg -q up -r 0
768 $ echo head1 > foo
768 $ echo head1 > foo
769 $ hg commit -m head1
769 $ hg commit -m head1
770 created new head
770 created new head
771 $ hg bookmark head1
771 $ hg bookmark head1
772 $ hg -q up -r 0
772 $ hg -q up -r 0
773 $ echo head2 > foo
773 $ echo head2 > foo
774 $ hg commit -m head2
774 $ hg commit -m head2
775 created new head
775 created new head
776 $ hg bookmark head2
776 $ hg bookmark head2
777 $ hg -q up -r 0
777 $ hg -q up -r 0
778 $ hg branch branch1
778 $ hg branch branch1
779 marked working directory as branch branch1
779 marked working directory as branch branch1
780 (branches are permanent and global, did you want a bookmark?)
780 (branches are permanent and global, did you want a bookmark?)
781 $ echo branch1 > foo
781 $ echo branch1 > foo
782 $ hg commit -m branch1
782 $ hg commit -m branch1
783 $ hg -q up -r 0
783 $ hg -q up -r 0
784 $ hg branch branch2
784 $ hg branch branch2
785 marked working directory as branch branch2
785 marked working directory as branch branch2
786 $ echo branch2 > foo
786 $ echo branch2 > foo
787 $ hg commit -m branch2
787 $ hg commit -m branch2
788 $ cd ..
788 $ cd ..
789 $ hg init source2
789 $ hg init source2
790 $ cd source2
790 $ cd source2
791 $ echo initial2 > foo
791 $ echo initial2 > foo
792 $ hg -q commit -A -m initial2
792 $ hg -q commit -A -m initial2
793 $ echo second > foo
793 $ echo second > foo
794 $ hg commit -m second
794 $ hg commit -m second
795 $ cd ..
795 $ cd ..
796
796
797 Clone with auto share from an empty repo should not result in share
797 Clone with auto share from an empty repo should not result in share
798
798
799 $ mkdir share
799 $ mkdir share
800 $ hg --config share.pool=share clone empty share-empty
800 $ hg --config share.pool=share clone empty share-empty
801 (not using pooled storage: remote appears to be empty)
801 (not using pooled storage: remote appears to be empty)
802 updating to branch default
802 updating to branch default
803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
804 $ ls share
804 $ ls share
805 $ test -d share-empty/.hg/store
805 $ test -d share-empty/.hg/store
806 $ test -f share-empty/.hg/sharedpath
806 $ test -f share-empty/.hg/sharedpath
807 [1]
807 [1]
808
808
809 Clone with auto share from a repo with filtered revision 0 should not result in share
809 Clone with auto share from a repo with filtered revision 0 should not result in share
810
810
811 $ hg --config share.pool=share clone filteredrev0 share-filtered
811 $ hg --config share.pool=share clone filteredrev0 share-filtered
812 (not using pooled storage: unable to resolve identity of remote)
812 (not using pooled storage: unable to resolve identity of remote)
813 requesting all changes
813 requesting all changes
814 adding changesets
814 adding changesets
815 adding manifests
815 adding manifests
816 adding file changes
816 adding file changes
817 added 1 changesets with 1 changes to 1 files
817 added 1 changesets with 1 changes to 1 files
818 new changesets e082c1832e09
818 new changesets e082c1832e09
819 updating to branch default
819 updating to branch default
820 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
820 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
821
821
822 Clone from repo with content should result in shared store being created
822 Clone from repo with content should result in shared store being created
823
823
824 $ hg --config share.pool=share clone source1a share-dest1a
824 $ hg --config share.pool=share clone source1a share-dest1a
825 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
825 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
826 requesting all changes
826 requesting all changes
827 adding changesets
827 adding changesets
828 adding manifests
828 adding manifests
829 adding file changes
829 adding file changes
830 added 3 changesets with 3 changes to 1 files
830 added 3 changesets with 3 changes to 1 files
831 new changesets b5f04eac9d8f:e5bfe23c0b47
831 new changesets b5f04eac9d8f:e5bfe23c0b47
832 searching for changes
832 searching for changes
833 no changes found
833 no changes found
834 adding remote bookmark bookA
834 adding remote bookmark bookA
835 updating working directory
835 updating working directory
836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
837
837
838 The shared repo should have been created
838 The shared repo should have been created
839
839
840 $ ls share
840 $ ls share
841 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
841 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
842
842
843 The destination should point to it
843 The destination should point to it
844
844
845 $ cat share-dest1a/.hg/sharedpath; echo
845 $ cat share-dest1a/.hg/sharedpath; echo
846 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
846 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
847
847
848 The destination should have bookmarks
848 The destination should have bookmarks
849
849
850 $ hg -R share-dest1a bookmarks
850 $ hg -R share-dest1a bookmarks
851 bookA 2:e5bfe23c0b47
851 bookA 2:e5bfe23c0b47
852
852
853 The default path should be the remote, not the share
853 The default path should be the remote, not the share
854
854
855 $ hg -R share-dest1a config paths.default
855 $ hg -R share-dest1a config paths.default
856 $TESTTMP/source1a
856 $TESTTMP/source1a
857
857
858 Clone with existing share dir should result in pull + share
858 Clone with existing share dir should result in pull + share
859
859
860 $ hg --config share.pool=share clone source1b share-dest1b
860 $ hg --config share.pool=share clone source1b share-dest1b
861 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
861 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
862 searching for changes
862 searching for changes
863 adding changesets
863 adding changesets
864 adding manifests
864 adding manifests
865 adding file changes
865 adding file changes
866 added 4 changesets with 4 changes to 1 files (+4 heads)
866 added 4 changesets with 4 changes to 1 files (+4 heads)
867 adding remote bookmark head1
867 adding remote bookmark head1
868 adding remote bookmark head2
868 adding remote bookmark head2
869 new changesets 4a8dc1ab4c13:6bacf4683960
869 new changesets 4a8dc1ab4c13:6bacf4683960
870 updating working directory
870 updating working directory
871 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
872
872
873 $ ls share
873 $ ls share
874 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
874 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
875
875
876 $ cat share-dest1b/.hg/sharedpath; echo
876 $ cat share-dest1b/.hg/sharedpath; echo
877 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
877 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
878
878
879 We only get bookmarks from the remote, not everything in the share
879 We only get bookmarks from the remote, not everything in the share
880
880
881 $ hg -R share-dest1b bookmarks
881 $ hg -R share-dest1b bookmarks
882 head1 3:4a8dc1ab4c13
882 head1 3:4a8dc1ab4c13
883 head2 4:99f71071f117
883 head2 4:99f71071f117
884
884
885 Default path should be source, not share.
885 Default path should be source, not share.
886
886
887 $ hg -R share-dest1b config paths.default
887 $ hg -R share-dest1b config paths.default
888 $TESTTMP/source1b
888 $TESTTMP/source1b
889
889
890 Checked out revision should be head of default branch
890 Checked out revision should be head of default branch
891
891
892 $ hg -R share-dest1b log -r .
892 $ hg -R share-dest1b log -r .
893 changeset: 4:99f71071f117
893 changeset: 4:99f71071f117
894 bookmark: head2
894 bookmark: head2
895 parent: 0:b5f04eac9d8f
895 parent: 0:b5f04eac9d8f
896 user: test
896 user: test
897 date: Thu Jan 01 00:00:00 1970 +0000
897 date: Thu Jan 01 00:00:00 1970 +0000
898 summary: head2
898 summary: head2
899
899
900
900
901 Clone from unrelated repo should result in new share
901 Clone from unrelated repo should result in new share
902
902
903 $ hg --config share.pool=share clone source2 share-dest2
903 $ hg --config share.pool=share clone source2 share-dest2
904 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
904 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
905 requesting all changes
905 requesting all changes
906 adding changesets
906 adding changesets
907 adding manifests
907 adding manifests
908 adding file changes
908 adding file changes
909 added 2 changesets with 2 changes to 1 files
909 added 2 changesets with 2 changes to 1 files
910 new changesets 22aeff664783:63cf6c3dba4a
910 new changesets 22aeff664783:63cf6c3dba4a
911 searching for changes
911 searching for changes
912 no changes found
912 no changes found
913 updating working directory
913 updating working directory
914 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
914 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
915
915
916 $ ls share
916 $ ls share
917 22aeff664783fd44c6d9b435618173c118c3448e
917 22aeff664783fd44c6d9b435618173c118c3448e
918 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
918 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
919
919
920 remote naming mode works as advertised
920 remote naming mode works as advertised
921
921
922 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
922 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
923 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
923 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
924 requesting all changes
924 requesting all changes
925 adding changesets
925 adding changesets
926 adding manifests
926 adding manifests
927 adding file changes
927 adding file changes
928 added 3 changesets with 3 changes to 1 files
928 added 3 changesets with 3 changes to 1 files
929 new changesets b5f04eac9d8f:e5bfe23c0b47
929 new changesets b5f04eac9d8f:e5bfe23c0b47
930 searching for changes
930 searching for changes
931 no changes found
931 no changes found
932 adding remote bookmark bookA
932 adding remote bookmark bookA
933 updating working directory
933 updating working directory
934 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
934 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
935
935
936 $ ls shareremote
936 $ ls shareremote
937 195bb1fcdb595c14a6c13e0269129ed78f6debde
937 195bb1fcdb595c14a6c13e0269129ed78f6debde
938
938
939 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
939 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
940 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
940 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
941 requesting all changes
941 requesting all changes
942 adding changesets
942 adding changesets
943 adding manifests
943 adding manifests
944 adding file changes
944 adding file changes
945 added 6 changesets with 6 changes to 1 files (+4 heads)
945 added 6 changesets with 6 changes to 1 files (+4 heads)
946 new changesets b5f04eac9d8f:6bacf4683960
946 new changesets b5f04eac9d8f:6bacf4683960
947 searching for changes
947 searching for changes
948 no changes found
948 no changes found
949 adding remote bookmark head1
949 adding remote bookmark head1
950 adding remote bookmark head2
950 adding remote bookmark head2
951 updating working directory
951 updating working directory
952 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
952 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
953
953
954 $ ls shareremote
954 $ ls shareremote
955 195bb1fcdb595c14a6c13e0269129ed78f6debde
955 195bb1fcdb595c14a6c13e0269129ed78f6debde
956 c0d4f83847ca2a873741feb7048a45085fd47c46
956 c0d4f83847ca2a873741feb7048a45085fd47c46
957
957
958 request to clone a single revision is respected in sharing mode
958 request to clone a single revision is respected in sharing mode
959
959
960 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
960 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
961 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
961 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
962 adding changesets
962 adding changesets
963 adding manifests
963 adding manifests
964 adding file changes
964 adding file changes
965 added 2 changesets with 2 changes to 1 files
965 added 2 changesets with 2 changes to 1 files
966 new changesets b5f04eac9d8f:4a8dc1ab4c13
966 new changesets b5f04eac9d8f:4a8dc1ab4c13
967 no changes found
967 no changes found
968 adding remote bookmark head1
968 adding remote bookmark head1
969 updating working directory
969 updating working directory
970 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
970 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
971
971
972 $ hg -R share-1arev log -G
972 $ hg -R share-1arev log -G
973 @ changeset: 1:4a8dc1ab4c13
973 @ changeset: 1:4a8dc1ab4c13
974 | bookmark: head1
974 | bookmark: head1
975 | tag: tip
975 | tag: tip
976 | user: test
976 | user: test
977 | date: Thu Jan 01 00:00:00 1970 +0000
977 | date: Thu Jan 01 00:00:00 1970 +0000
978 | summary: head1
978 | summary: head1
979 |
979 |
980 o changeset: 0:b5f04eac9d8f
980 o changeset: 0:b5f04eac9d8f
981 user: test
981 user: test
982 date: Thu Jan 01 00:00:00 1970 +0000
982 date: Thu Jan 01 00:00:00 1970 +0000
983 summary: initial
983 summary: initial
984
984
985
985
986 making another clone should only pull down requested rev
986 making another clone should only pull down requested rev
987
987
988 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
988 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
989 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
989 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
990 searching for changes
990 searching for changes
991 adding changesets
991 adding changesets
992 adding manifests
992 adding manifests
993 adding file changes
993 adding file changes
994 added 1 changesets with 1 changes to 1 files (+1 heads)
994 added 1 changesets with 1 changes to 1 files (+1 heads)
995 adding remote bookmark head1
995 adding remote bookmark head1
996 adding remote bookmark head2
996 adding remote bookmark head2
997 new changesets 99f71071f117
997 new changesets 99f71071f117
998 updating working directory
998 updating working directory
999 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000
1000
1001 $ hg -R share-1brev log -G
1001 $ hg -R share-1brev log -G
1002 @ changeset: 2:99f71071f117
1002 @ changeset: 2:99f71071f117
1003 | bookmark: head2
1003 | bookmark: head2
1004 | tag: tip
1004 | tag: tip
1005 | parent: 0:b5f04eac9d8f
1005 | parent: 0:b5f04eac9d8f
1006 | user: test
1006 | user: test
1007 | date: Thu Jan 01 00:00:00 1970 +0000
1007 | date: Thu Jan 01 00:00:00 1970 +0000
1008 | summary: head2
1008 | summary: head2
1009 |
1009 |
1010 | o changeset: 1:4a8dc1ab4c13
1010 | o changeset: 1:4a8dc1ab4c13
1011 |/ bookmark: head1
1011 |/ bookmark: head1
1012 | user: test
1012 | user: test
1013 | date: Thu Jan 01 00:00:00 1970 +0000
1013 | date: Thu Jan 01 00:00:00 1970 +0000
1014 | summary: head1
1014 | summary: head1
1015 |
1015 |
1016 o changeset: 0:b5f04eac9d8f
1016 o changeset: 0:b5f04eac9d8f
1017 user: test
1017 user: test
1018 date: Thu Jan 01 00:00:00 1970 +0000
1018 date: Thu Jan 01 00:00:00 1970 +0000
1019 summary: initial
1019 summary: initial
1020
1020
1021
1021
1022 Request to clone a single branch is respected in sharing mode
1022 Request to clone a single branch is respected in sharing mode
1023
1023
1024 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1024 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1025 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1025 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1026 adding changesets
1026 adding changesets
1027 adding manifests
1027 adding manifests
1028 adding file changes
1028 adding file changes
1029 added 2 changesets with 2 changes to 1 files
1029 added 2 changesets with 2 changes to 1 files
1030 new changesets b5f04eac9d8f:5f92a6c1a1b1
1030 new changesets b5f04eac9d8f:5f92a6c1a1b1
1031 no changes found
1031 no changes found
1032 updating working directory
1032 updating working directory
1033 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1033 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1034
1034
1035 $ hg -R share-1bbranch1 log -G
1035 $ hg -R share-1bbranch1 log -G
1036 o changeset: 1:5f92a6c1a1b1
1036 o changeset: 1:5f92a6c1a1b1
1037 | branch: branch1
1037 | branch: branch1
1038 | tag: tip
1038 | tag: tip
1039 | user: test
1039 | user: test
1040 | date: Thu Jan 01 00:00:00 1970 +0000
1040 | date: Thu Jan 01 00:00:00 1970 +0000
1041 | summary: branch1
1041 | summary: branch1
1042 |
1042 |
1043 @ changeset: 0:b5f04eac9d8f
1043 @ changeset: 0:b5f04eac9d8f
1044 user: test
1044 user: test
1045 date: Thu Jan 01 00:00:00 1970 +0000
1045 date: Thu Jan 01 00:00:00 1970 +0000
1046 summary: initial
1046 summary: initial
1047
1047
1048
1048
1049 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1049 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1050 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1050 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1051 searching for changes
1051 searching for changes
1052 adding changesets
1052 adding changesets
1053 adding manifests
1053 adding manifests
1054 adding file changes
1054 adding file changes
1055 added 1 changesets with 1 changes to 1 files (+1 heads)
1055 added 1 changesets with 1 changes to 1 files (+1 heads)
1056 new changesets 6bacf4683960
1056 new changesets 6bacf4683960
1057 updating working directory
1057 updating working directory
1058 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1058 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1059
1059
1060 $ hg -R share-1bbranch2 log -G
1060 $ hg -R share-1bbranch2 log -G
1061 o changeset: 2:6bacf4683960
1061 o changeset: 2:6bacf4683960
1062 | branch: branch2
1062 | branch: branch2
1063 | tag: tip
1063 | tag: tip
1064 | parent: 0:b5f04eac9d8f
1064 | parent: 0:b5f04eac9d8f
1065 | user: test
1065 | user: test
1066 | date: Thu Jan 01 00:00:00 1970 +0000
1066 | date: Thu Jan 01 00:00:00 1970 +0000
1067 | summary: branch2
1067 | summary: branch2
1068 |
1068 |
1069 | o changeset: 1:5f92a6c1a1b1
1069 | o changeset: 1:5f92a6c1a1b1
1070 |/ branch: branch1
1070 |/ branch: branch1
1071 | user: test
1071 | user: test
1072 | date: Thu Jan 01 00:00:00 1970 +0000
1072 | date: Thu Jan 01 00:00:00 1970 +0000
1073 | summary: branch1
1073 | summary: branch1
1074 |
1074 |
1075 @ changeset: 0:b5f04eac9d8f
1075 @ changeset: 0:b5f04eac9d8f
1076 user: test
1076 user: test
1077 date: Thu Jan 01 00:00:00 1970 +0000
1077 date: Thu Jan 01 00:00:00 1970 +0000
1078 summary: initial
1078 summary: initial
1079
1079
1080
1080
1081 -U is respected in share clone mode
1081 -U is respected in share clone mode
1082
1082
1083 $ hg --config share.pool=share clone -U source1a share-1anowc
1083 $ hg --config share.pool=share clone -U source1a share-1anowc
1084 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1084 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1085 searching for changes
1085 searching for changes
1086 no changes found
1086 no changes found
1087 adding remote bookmark bookA
1087 adding remote bookmark bookA
1088
1088
1089 $ ls share-1anowc
1089 $ ls share-1anowc
1090
1090
1091 Test that auto sharing doesn't cause failure of "hg clone local remote"
1091 Test that auto sharing doesn't cause failure of "hg clone local remote"
1092
1092
1093 $ cd $TESTTMP
1093 $ cd $TESTTMP
1094 $ hg -R a id -r 0
1094 $ hg -R a id -r 0
1095 acb14030fe0a
1095 acb14030fe0a
1096 $ hg id -R remote -r 0
1096 $ hg id -R remote -r 0
1097 abort: repository remote not found!
1097 abort: repository remote not found!
1098 [255]
1098 [255]
1099 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1099 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1100 $ hg -R remote id -r 0
1100 $ hg -R remote id -r 0
1101 acb14030fe0a
1101 acb14030fe0a
1102
1102
1103 Cloning into pooled storage doesn't race (issue5104)
1103 Cloning into pooled storage doesn't race (issue5104)
1104
1104
1105 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1105 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1106 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1106 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1107 $ wait
1107 $ wait
1108
1108
1109 $ hg -R share-destrace1 log -r tip
1109 $ hg -R share-destrace1 log -r tip
1110 changeset: 2:e5bfe23c0b47
1110 changeset: 2:e5bfe23c0b47
1111 bookmark: bookA
1111 bookmark: bookA
1112 tag: tip
1112 tag: tip
1113 user: test
1113 user: test
1114 date: Thu Jan 01 00:00:00 1970 +0000
1114 date: Thu Jan 01 00:00:00 1970 +0000
1115 summary: 1a
1115 summary: 1a
1116
1116
1117
1117
1118 $ hg -R share-destrace2 log -r tip
1118 $ hg -R share-destrace2 log -r tip
1119 changeset: 2:e5bfe23c0b47
1119 changeset: 2:e5bfe23c0b47
1120 bookmark: bookA
1120 bookmark: bookA
1121 tag: tip
1121 tag: tip
1122 user: test
1122 user: test
1123 date: Thu Jan 01 00:00:00 1970 +0000
1123 date: Thu Jan 01 00:00:00 1970 +0000
1124 summary: 1a
1124 summary: 1a
1125
1125
1126 One repo should be new, the other should be shared from the pool. We
1126 One repo should be new, the other should be shared from the pool. We
1127 don't care which is which, so we just make sure we always print the
1127 don't care which is which, so we just make sure we always print the
1128 one containing "new pooled" first, then one one containing "existing
1128 one containing "new pooled" first, then one one containing "existing
1129 pooled".
1129 pooled".
1130
1130
1131 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1131 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1132 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1132 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1133 requesting all changes
1133 requesting all changes
1134 adding changesets
1134 adding changesets
1135 adding manifests
1135 adding manifests
1136 adding file changes
1136 adding file changes
1137 added 3 changesets with 3 changes to 1 files
1137 added 3 changesets with 3 changes to 1 files
1138 new changesets b5f04eac9d8f:e5bfe23c0b47
1138 new changesets b5f04eac9d8f:e5bfe23c0b47
1139 searching for changes
1139 searching for changes
1140 no changes found
1140 no changes found
1141 adding remote bookmark bookA
1141 adding remote bookmark bookA
1142 updating working directory
1142 updating working directory
1143 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1143 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144
1144
1145 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1145 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1146 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1146 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1147 searching for changes
1147 searching for changes
1148 no changes found
1148 no changes found
1149 adding remote bookmark bookA
1149 adding remote bookmark bookA
1150 updating working directory
1150 updating working directory
1151 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1151 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1152
1152
1153 SEC: check for unsafe ssh url
1153 SEC: check for unsafe ssh url
1154
1154
1155 $ cat >> $HGRCPATH << EOF
1155 $ cat >> $HGRCPATH << EOF
1156 > [ui]
1156 > [ui]
1157 > ssh = sh -c "read l; read l; read l"
1157 > ssh = sh -c "read l; read l; read l"
1158 > EOF
1158 > EOF
1159
1159
1160 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1160 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1161 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1161 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1162 [255]
1162 [255]
1163 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1163 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1164 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1164 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1165 [255]
1165 [255]
1166 $ hg clone 'ssh://fakehost|touch%20owned/path'
1166 $ hg clone 'ssh://fakehost|touch%20owned/path'
1167 abort: no suitable response from remote hg!
1167 abort: no suitable response from remote hg!
1168 [255]
1168 [255]
1169 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1169 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1170 abort: no suitable response from remote hg!
1170 abort: no suitable response from remote hg!
1171 [255]
1171 [255]
1172
1172
1173 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1173 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1174 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1174 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1175 [255]
1175 [255]
1176
1176
1177 #if windows
1177 #if windows
1178 $ hg clone "ssh://%26touch%20owned%20/" --debug
1178 $ hg clone "ssh://%26touch%20owned%20/" --debug
1179 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1179 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1180 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1180 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1181 sending hello command
1181 sending hello command
1182 sending between command
1182 sending between command
1183 abort: no suitable response from remote hg!
1183 abort: no suitable response from remote hg!
1184 [255]
1184 [255]
1185 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1185 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1186 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1186 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1187 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1187 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1188 sending hello command
1188 sending hello command
1189 sending between command
1189 sending between command
1190 abort: no suitable response from remote hg!
1190 abort: no suitable response from remote hg!
1191 [255]
1191 [255]
1192 #else
1192 #else
1193 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1193 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1194 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1194 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1195 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1195 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1196 sending hello command
1196 sending hello command
1197 sending between command
1197 sending between command
1198 abort: no suitable response from remote hg!
1198 abort: no suitable response from remote hg!
1199 [255]
1199 [255]
1200 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1200 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1201 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1201 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1202 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1202 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1203 sending hello command
1203 sending hello command
1204 sending between command
1204 sending between command
1205 abort: no suitable response from remote hg!
1205 abort: no suitable response from remote hg!
1206 [255]
1206 [255]
1207 #endif
1207 #endif
1208
1208
1209 $ hg clone "ssh://v-alid.example.com/" --debug
1209 $ hg clone "ssh://v-alid.example.com/" --debug
1210 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1210 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1211 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1211 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1212 sending hello command
1212 sending hello command
1213 sending between command
1213 sending between command
1214 abort: no suitable response from remote hg!
1214 abort: no suitable response from remote hg!
1215 [255]
1215 [255]
1216
1216
1217 We should not have created a file named owned - if it exists, the
1217 We should not have created a file named owned - if it exists, the
1218 attack succeeded.
1218 attack succeeded.
1219 $ if test -f owned; then echo 'you got owned'; fi
1219 $ if test -f owned; then echo 'you got owned'; fi
1220
1220
1221 Cloning without fsmonitor enabled does not print a warning for small repos
1221 Cloning without fsmonitor enabled does not print a warning for small repos
1222
1222
1223 $ hg clone a fsmonitor-default
1223 $ hg clone a fsmonitor-default
1224 updating to bookmark @ on branch stable
1224 updating to bookmark @ on branch stable
1225 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1225 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1226
1226
1227 Lower the warning threshold to simulate a large repo
1227 Lower the warning threshold to simulate a large repo
1228
1228
1229 $ cat >> $HGRCPATH << EOF
1229 $ cat >> $HGRCPATH << EOF
1230 > [fsmonitor]
1230 > [fsmonitor]
1231 > warn_update_file_count = 2
1231 > warn_update_file_count = 2
1232 > EOF
1232 > EOF
1233
1233
1234 We should see a warning about no fsmonitor on supported platforms
1234 We should see a warning about no fsmonitor on supported platforms
1235
1235
1236 #if linuxormacos no-fsmonitor
1236 #if linuxormacos no-fsmonitor
1237 $ hg clone a nofsmonitor
1237 $ hg clone a nofsmonitor
1238 updating to bookmark @ on branch stable
1238 updating to bookmark @ on branch stable
1239 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1239 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1240 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1240 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1241 #else
1241 #else
1242 $ hg clone a nofsmonitor
1242 $ hg clone a nofsmonitor
1243 updating to bookmark @ on branch stable
1243 updating to bookmark @ on branch stable
1244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1245 #endif
1245 #endif
1246
1246
1247 We should not see warning about fsmonitor when it is enabled
1247 We should not see warning about fsmonitor when it is enabled
1248
1248
1249 #if fsmonitor
1249 #if fsmonitor
1250 $ hg clone a fsmonitor-enabled
1250 $ hg clone a fsmonitor-enabled
1251 updating to bookmark @ on branch stable
1251 updating to bookmark @ on branch stable
1252 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1252 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1253 #endif
1253 #endif
1254
1254
1255 We can disable the fsmonitor warning
1255 We can disable the fsmonitor warning
1256
1256
1257 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1257 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1258 updating to bookmark @ on branch stable
1258 updating to bookmark @ on branch stable
1259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1260
1260
1261 Loaded fsmonitor but disabled in config should still print warning
1261 Loaded fsmonitor but disabled in config should still print warning
1262
1262
1263 #if linuxormacos fsmonitor
1263 #if linuxormacos fsmonitor
1264 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1264 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1265 updating to bookmark @ on branch stable
1265 updating to bookmark @ on branch stable
1266 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1266 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1267 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1267 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1268 #endif
1268 #endif
1269
1269
1270 Warning not printed if working directory isn't empty
1270 Warning not printed if working directory isn't empty
1271
1271
1272 $ hg -q clone a fsmonitor-update
1272 $ hg -q clone a fsmonitor-update
1273 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1273 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1274 $ cd fsmonitor-update
1274 $ cd fsmonitor-update
1275 $ hg up acb14030fe0a
1275 $ hg up acb14030fe0a
1276 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1276 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1277 (leaving bookmark @)
1277 (leaving bookmark @)
1278 $ hg up cf0fe1914066
1278 $ hg up cf0fe1914066
1279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1280
1280
1281 `hg update` from null revision also prints
1281 `hg update` from null revision also prints
1282
1282
1283 $ hg up null
1283 $ hg up null
1284 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1284 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1285
1285
1286 #if linuxormacos no-fsmonitor
1286 #if linuxormacos no-fsmonitor
1287 $ hg up cf0fe1914066
1287 $ hg up cf0fe1914066
1288 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1288 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1289 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1289 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1290 #else
1290 #else
1291 $ hg up cf0fe1914066
1291 $ hg up cf0fe1914066
1292 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1292 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1293 #endif
1293 #endif
1294
1294
1295 $ cd ..
1295 $ cd ..
1296
1296
@@ -1,432 +1,432 b''
1 #require hardlink reporevlogstore
1 #require hardlink reporevlogstore
2
2
3 $ cat > nlinks.py <<EOF
3 $ cat > nlinks.py <<EOF
4 > from __future__ import print_function
4 > from __future__ import print_function
5 > import sys
5 > import sys
6 > from mercurial import util
6 > from mercurial import util
7 > for f in sorted(sys.stdin.readlines()):
7 > for f in sorted(sys.stdin.readlines()):
8 > f = f[:-1]
8 > f = f[:-1]
9 > print(util.nlinks(f), f)
9 > print(util.nlinks(f), f)
10 > EOF
10 > EOF
11
11
12 $ nlinksdir()
12 $ nlinksdir()
13 > {
13 > {
14 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
14 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
15 > }
15 > }
16
16
17 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
17 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
18
18
19 $ cat > linkcp.py <<EOF
19 $ cat > linkcp.py <<EOF
20 > from __future__ import absolute_import
20 > from __future__ import absolute_import
21 > import sys
21 > import sys
22 > from mercurial import pycompat, util
22 > from mercurial import pycompat, util
23 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
23 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
24 > pycompat.fsencode(sys.argv[2]), hardlink=True)
24 > pycompat.fsencode(sys.argv[2]), hardlink=True)
25 > EOF
25 > EOF
26
26
27 $ linkcp()
27 $ linkcp()
28 > {
28 > {
29 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
29 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
30 > }
30 > }
31
31
32 Prepare repo r1:
32 Prepare repo r1:
33
33
34 $ hg init r1
34 $ hg init r1
35 $ cd r1
35 $ cd r1
36
36
37 $ echo c1 > f1
37 $ echo c1 > f1
38 $ hg add f1
38 $ hg add f1
39 $ hg ci -m0
39 $ hg ci -m0
40
40
41 $ mkdir d1
41 $ mkdir d1
42 $ cd d1
42 $ cd d1
43 $ echo c2 > f2
43 $ echo c2 > f2
44 $ hg add f2
44 $ hg add f2
45 $ hg ci -m1
45 $ hg ci -m1
46 $ cd ../..
46 $ cd ../..
47
47
48 $ nlinksdir r1/.hg/store
48 $ nlinksdir r1/.hg/store
49 1 r1/.hg/store/00changelog.i
49 1 r1/.hg/store/00changelog.i
50 1 r1/.hg/store/00manifest.i
50 1 r1/.hg/store/00manifest.i
51 1 r1/.hg/store/data/d1/f2.i
51 1 r1/.hg/store/data/d1/f2.i
52 1 r1/.hg/store/data/f1.i
52 1 r1/.hg/store/data/f1.i
53 1 r1/.hg/store/fncache (repofncache !)
53 1 r1/.hg/store/fncache (repofncache !)
54 1 r1/.hg/store/phaseroots
54 1 r1/.hg/store/phaseroots
55 1 r1/.hg/store/undo
55 1 r1/.hg/store/undo
56 1 r1/.hg/store/undo.backup.fncache (repofncache !)
56 1 r1/.hg/store/undo.backup.fncache (repofncache !)
57 1 r1/.hg/store/undo.backupfiles
57 1 r1/.hg/store/undo.backupfiles
58 1 r1/.hg/store/undo.phaseroots
58 1 r1/.hg/store/undo.phaseroots
59
59
60
60
61 Create hardlinked clone r2:
61 Create hardlinked clone r2:
62
62
63 $ hg clone -U --debug r1 r2 --config progress.debug=true
63 $ hg clone -U --debug r1 r2 --config progress.debug=true
64 linking: 1
64 linking: 1 files
65 linking: 2
65 linking: 2 files
66 linking: 3
66 linking: 3 files
67 linking: 4
67 linking: 4 files
68 linking: 5
68 linking: 5 files
69 linking: 6
69 linking: 6 files
70 linking: 7
70 linking: 7 files
71 linked 7 files
71 linked 7 files
72
72
73 Create non-hardlinked clone r3:
73 Create non-hardlinked clone r3:
74
74
75 $ hg clone --pull r1 r3
75 $ hg clone --pull r1 r3
76 requesting all changes
76 requesting all changes
77 adding changesets
77 adding changesets
78 adding manifests
78 adding manifests
79 adding file changes
79 adding file changes
80 added 2 changesets with 2 changes to 2 files
80 added 2 changesets with 2 changes to 2 files
81 new changesets 40d85e9847f2:7069c422939c
81 new changesets 40d85e9847f2:7069c422939c
82 updating to branch default
82 updating to branch default
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
84
84
85
85
86 Repos r1 and r2 should now contain hardlinked files:
86 Repos r1 and r2 should now contain hardlinked files:
87
87
88 $ nlinksdir r1/.hg/store
88 $ nlinksdir r1/.hg/store
89 2 r1/.hg/store/00changelog.i
89 2 r1/.hg/store/00changelog.i
90 2 r1/.hg/store/00manifest.i
90 2 r1/.hg/store/00manifest.i
91 2 r1/.hg/store/data/d1/f2.i
91 2 r1/.hg/store/data/d1/f2.i
92 2 r1/.hg/store/data/f1.i
92 2 r1/.hg/store/data/f1.i
93 2 r1/.hg/store/fncache (repofncache !)
93 2 r1/.hg/store/fncache (repofncache !)
94 1 r1/.hg/store/phaseroots
94 1 r1/.hg/store/phaseroots
95 1 r1/.hg/store/undo
95 1 r1/.hg/store/undo
96 1 r1/.hg/store/undo.backup.fncache (repofncache !)
96 1 r1/.hg/store/undo.backup.fncache (repofncache !)
97 1 r1/.hg/store/undo.backupfiles
97 1 r1/.hg/store/undo.backupfiles
98 1 r1/.hg/store/undo.phaseroots
98 1 r1/.hg/store/undo.phaseroots
99
99
100 $ nlinksdir r2/.hg/store
100 $ nlinksdir r2/.hg/store
101 2 r2/.hg/store/00changelog.i
101 2 r2/.hg/store/00changelog.i
102 2 r2/.hg/store/00manifest.i
102 2 r2/.hg/store/00manifest.i
103 2 r2/.hg/store/data/d1/f2.i
103 2 r2/.hg/store/data/d1/f2.i
104 2 r2/.hg/store/data/f1.i
104 2 r2/.hg/store/data/f1.i
105 2 r2/.hg/store/fncache (repofncache !)
105 2 r2/.hg/store/fncache (repofncache !)
106
106
107 Repo r3 should not be hardlinked:
107 Repo r3 should not be hardlinked:
108
108
109 $ nlinksdir r3/.hg/store
109 $ nlinksdir r3/.hg/store
110 1 r3/.hg/store/00changelog.i
110 1 r3/.hg/store/00changelog.i
111 1 r3/.hg/store/00manifest.i
111 1 r3/.hg/store/00manifest.i
112 1 r3/.hg/store/data/d1/f2.i
112 1 r3/.hg/store/data/d1/f2.i
113 1 r3/.hg/store/data/f1.i
113 1 r3/.hg/store/data/f1.i
114 1 r3/.hg/store/fncache (repofncache !)
114 1 r3/.hg/store/fncache (repofncache !)
115 1 r3/.hg/store/phaseroots
115 1 r3/.hg/store/phaseroots
116 1 r3/.hg/store/undo
116 1 r3/.hg/store/undo
117 1 r3/.hg/store/undo.backupfiles
117 1 r3/.hg/store/undo.backupfiles
118 1 r3/.hg/store/undo.phaseroots
118 1 r3/.hg/store/undo.phaseroots
119
119
120
120
121 Create a non-inlined filelog in r3:
121 Create a non-inlined filelog in r3:
122
122
123 $ cd r3/d1
123 $ cd r3/d1
124 >>> f = open('data1', 'wb')
124 >>> f = open('data1', 'wb')
125 >>> for x in range(10000):
125 >>> for x in range(10000):
126 ... f.write(b"%d\n" % x) and None
126 ... f.write(b"%d\n" % x) and None
127 >>> f.close()
127 >>> f.close()
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
129 > cat data1 >> f2
129 > cat data1 >> f2
130 > hg commit -m$j
130 > hg commit -m$j
131 > done
131 > done
132 $ cd ../..
132 $ cd ../..
133
133
134 $ nlinksdir r3/.hg/store
134 $ nlinksdir r3/.hg/store
135 1 r3/.hg/store/00changelog.i
135 1 r3/.hg/store/00changelog.i
136 1 r3/.hg/store/00manifest.i
136 1 r3/.hg/store/00manifest.i
137 1 r3/.hg/store/data/d1/f2.d
137 1 r3/.hg/store/data/d1/f2.d
138 1 r3/.hg/store/data/d1/f2.i
138 1 r3/.hg/store/data/d1/f2.i
139 1 r3/.hg/store/data/f1.i
139 1 r3/.hg/store/data/f1.i
140 1 r3/.hg/store/fncache (repofncache !)
140 1 r3/.hg/store/fncache (repofncache !)
141 1 r3/.hg/store/phaseroots
141 1 r3/.hg/store/phaseroots
142 1 r3/.hg/store/undo
142 1 r3/.hg/store/undo
143 1 r3/.hg/store/undo.backup.fncache (repofncache !)
143 1 r3/.hg/store/undo.backup.fncache (repofncache !)
144 1 r3/.hg/store/undo.backup.phaseroots
144 1 r3/.hg/store/undo.backup.phaseroots
145 1 r3/.hg/store/undo.backupfiles
145 1 r3/.hg/store/undo.backupfiles
146 1 r3/.hg/store/undo.phaseroots
146 1 r3/.hg/store/undo.phaseroots
147
147
148 Push to repo r1 should break up most hardlinks in r2:
148 Push to repo r1 should break up most hardlinks in r2:
149
149
150 $ hg -R r2 verify
150 $ hg -R r2 verify
151 checking changesets
151 checking changesets
152 checking manifests
152 checking manifests
153 crosschecking files in changesets and manifests
153 crosschecking files in changesets and manifests
154 checking files
154 checking files
155 checked 2 changesets with 2 changes to 2 files
155 checked 2 changesets with 2 changes to 2 files
156
156
157 $ cd r3
157 $ cd r3
158 $ hg push
158 $ hg push
159 pushing to $TESTTMP/r1
159 pushing to $TESTTMP/r1
160 searching for changes
160 searching for changes
161 adding changesets
161 adding changesets
162 adding manifests
162 adding manifests
163 adding file changes
163 adding file changes
164 added 10 changesets with 10 changes to 1 files
164 added 10 changesets with 10 changes to 1 files
165
165
166 $ cd ..
166 $ cd ..
167
167
168 $ nlinksdir r2/.hg/store
168 $ nlinksdir r2/.hg/store
169 1 r2/.hg/store/00changelog.i
169 1 r2/.hg/store/00changelog.i
170 1 r2/.hg/store/00manifest.i
170 1 r2/.hg/store/00manifest.i
171 1 r2/.hg/store/data/d1/f2.i
171 1 r2/.hg/store/data/d1/f2.i
172 2 r2/.hg/store/data/f1.i
172 2 r2/.hg/store/data/f1.i
173 [12] r2/\.hg/store/fncache (re) (repofncache !)
173 [12] r2/\.hg/store/fncache (re) (repofncache !)
174
174
175 #if hardlink-whitelisted repofncache
175 #if hardlink-whitelisted repofncache
176 $ nlinksdir r2/.hg/store/fncache
176 $ nlinksdir r2/.hg/store/fncache
177 2 r2/.hg/store/fncache
177 2 r2/.hg/store/fncache
178 #endif
178 #endif
179
179
180 $ hg -R r2 verify
180 $ hg -R r2 verify
181 checking changesets
181 checking changesets
182 checking manifests
182 checking manifests
183 crosschecking files in changesets and manifests
183 crosschecking files in changesets and manifests
184 checking files
184 checking files
185 checked 2 changesets with 2 changes to 2 files
185 checked 2 changesets with 2 changes to 2 files
186
186
187
187
188 $ cd r1
188 $ cd r1
189 $ hg up
189 $ hg up
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191
191
192 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
192 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
193
193
194 $ echo c1c1 >> f1
194 $ echo c1c1 >> f1
195 $ hg ci -m00
195 $ hg ci -m00
196 $ cd ..
196 $ cd ..
197
197
198 $ nlinksdir r2/.hg/store
198 $ nlinksdir r2/.hg/store
199 1 r2/.hg/store/00changelog.i
199 1 r2/.hg/store/00changelog.i
200 1 r2/.hg/store/00manifest.i
200 1 r2/.hg/store/00manifest.i
201 1 r2/.hg/store/data/d1/f2.i
201 1 r2/.hg/store/data/d1/f2.i
202 1 r2/.hg/store/data/f1.i
202 1 r2/.hg/store/data/f1.i
203 [12] r2/\.hg/store/fncache (re) (repofncache !)
203 [12] r2/\.hg/store/fncache (re) (repofncache !)
204
204
205 #if hardlink-whitelisted repofncache
205 #if hardlink-whitelisted repofncache
206 $ nlinksdir r2/.hg/store/fncache
206 $ nlinksdir r2/.hg/store/fncache
207 2 r2/.hg/store/fncache
207 2 r2/.hg/store/fncache
208 #endif
208 #endif
209
209
210 Create a file which exec permissions we will change
210 Create a file which exec permissions we will change
211 $ cd r3
211 $ cd r3
212 $ echo "echo hello world" > f3
212 $ echo "echo hello world" > f3
213 $ hg add f3
213 $ hg add f3
214 $ hg ci -mf3
214 $ hg ci -mf3
215 $ cd ..
215 $ cd ..
216
216
217 $ cd r3
217 $ cd r3
218 $ hg tip --template '{rev}:{node|short}\n'
218 $ hg tip --template '{rev}:{node|short}\n'
219 12:d3b77733a28a
219 12:d3b77733a28a
220 $ echo bla > f1
220 $ echo bla > f1
221 $ chmod +x f3
221 $ chmod +x f3
222 $ hg ci -m1
222 $ hg ci -m1
223 $ cd ..
223 $ cd ..
224
224
225 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
225 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
226
226
227 $ linkcp r3 r4
227 $ linkcp r3 r4
228
228
229 'checklink' is produced by hardlinking a symlink, which is undefined whether
229 'checklink' is produced by hardlinking a symlink, which is undefined whether
230 the symlink should be followed or not. It does behave differently on Linux and
230 the symlink should be followed or not. It does behave differently on Linux and
231 BSD. Just remove it so the test pass on both platforms.
231 BSD. Just remove it so the test pass on both platforms.
232
232
233 $ rm -f r4/.hg/cache/checklink
233 $ rm -f r4/.hg/cache/checklink
234
234
235 r4 has hardlinks in the working dir (not just inside .hg):
235 r4 has hardlinks in the working dir (not just inside .hg):
236
236
237 $ nlinksdir r4
237 $ nlinksdir r4
238 2 r4/.hg/00changelog.i
238 2 r4/.hg/00changelog.i
239 2 r4/.hg/branch
239 2 r4/.hg/branch
240 2 r4/.hg/cache/branch2-base
240 2 r4/.hg/cache/branch2-base
241 2 r4/.hg/cache/branch2-served
241 2 r4/.hg/cache/branch2-served
242 2 r4/.hg/cache/checkisexec (execbit !)
242 2 r4/.hg/cache/checkisexec (execbit !)
243 ? r4/.hg/cache/checklink-target (glob) (symlink !)
243 ? r4/.hg/cache/checklink-target (glob) (symlink !)
244 2 r4/.hg/cache/checknoexec (execbit !)
244 2 r4/.hg/cache/checknoexec (execbit !)
245 2 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
245 2 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
246 2 r4/.hg/cache/rbc-names-v1
246 2 r4/.hg/cache/rbc-names-v1
247 2 r4/.hg/cache/rbc-revs-v1
247 2 r4/.hg/cache/rbc-revs-v1
248 2 r4/.hg/dirstate
248 2 r4/.hg/dirstate
249 2 r4/.hg/fsmonitor.state (fsmonitor !)
249 2 r4/.hg/fsmonitor.state (fsmonitor !)
250 2 r4/.hg/hgrc
250 2 r4/.hg/hgrc
251 2 r4/.hg/last-message.txt
251 2 r4/.hg/last-message.txt
252 2 r4/.hg/requires
252 2 r4/.hg/requires
253 2 r4/.hg/store/00changelog.i
253 2 r4/.hg/store/00changelog.i
254 2 r4/.hg/store/00manifest.i
254 2 r4/.hg/store/00manifest.i
255 2 r4/.hg/store/data/d1/f2.d
255 2 r4/.hg/store/data/d1/f2.d
256 2 r4/.hg/store/data/d1/f2.i
256 2 r4/.hg/store/data/d1/f2.i
257 2 r4/.hg/store/data/f1.i
257 2 r4/.hg/store/data/f1.i
258 2 r4/.hg/store/data/f3.i
258 2 r4/.hg/store/data/f3.i
259 2 r4/.hg/store/fncache (repofncache !)
259 2 r4/.hg/store/fncache (repofncache !)
260 2 r4/.hg/store/phaseroots
260 2 r4/.hg/store/phaseroots
261 2 r4/.hg/store/undo
261 2 r4/.hg/store/undo
262 2 r4/.hg/store/undo.backup.fncache (repofncache !)
262 2 r4/.hg/store/undo.backup.fncache (repofncache !)
263 2 r4/.hg/store/undo.backup.phaseroots
263 2 r4/.hg/store/undo.backup.phaseroots
264 2 r4/.hg/store/undo.backupfiles
264 2 r4/.hg/store/undo.backupfiles
265 2 r4/.hg/store/undo.phaseroots
265 2 r4/.hg/store/undo.phaseroots
266 [24] r4/\.hg/undo\.backup\.dirstate (re)
266 [24] r4/\.hg/undo\.backup\.dirstate (re)
267 2 r4/.hg/undo.bookmarks
267 2 r4/.hg/undo.bookmarks
268 2 r4/.hg/undo.branch
268 2 r4/.hg/undo.branch
269 2 r4/.hg/undo.desc
269 2 r4/.hg/undo.desc
270 [24] r4/\.hg/undo\.dirstate (re)
270 [24] r4/\.hg/undo\.dirstate (re)
271 2 r4/d1/data1
271 2 r4/d1/data1
272 2 r4/d1/f2
272 2 r4/d1/f2
273 2 r4/f1
273 2 r4/f1
274 2 r4/f3
274 2 r4/f3
275
275
276 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
276 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
277 #if hardlink-whitelisted
277 #if hardlink-whitelisted
278 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
278 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
279 4 r4/.hg/undo.backup.dirstate
279 4 r4/.hg/undo.backup.dirstate
280 4 r4/.hg/undo.dirstate
280 4 r4/.hg/undo.dirstate
281 #endif
281 #endif
282
282
283
283
284 $ hg -R r4 up 12
284 $ hg -R r4 up 12
285 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
285 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
287
287
288 $ nlinksdir r4
288 $ nlinksdir r4
289 2 r4/.hg/00changelog.i
289 2 r4/.hg/00changelog.i
290 1 r4/.hg/branch
290 1 r4/.hg/branch
291 2 r4/.hg/cache/branch2-base
291 2 r4/.hg/cache/branch2-base
292 2 r4/.hg/cache/branch2-served
292 2 r4/.hg/cache/branch2-served
293 2 r4/.hg/cache/checkisexec (execbit !)
293 2 r4/.hg/cache/checkisexec (execbit !)
294 2 r4/.hg/cache/checklink-target (symlink !)
294 2 r4/.hg/cache/checklink-target (symlink !)
295 2 r4/.hg/cache/checknoexec (execbit !)
295 2 r4/.hg/cache/checknoexec (execbit !)
296 2 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
296 2 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
297 2 r4/.hg/cache/rbc-names-v1
297 2 r4/.hg/cache/rbc-names-v1
298 2 r4/.hg/cache/rbc-revs-v1
298 2 r4/.hg/cache/rbc-revs-v1
299 1 r4/.hg/dirstate
299 1 r4/.hg/dirstate
300 1 r4/.hg/fsmonitor.state (fsmonitor !)
300 1 r4/.hg/fsmonitor.state (fsmonitor !)
301 2 r4/.hg/hgrc
301 2 r4/.hg/hgrc
302 2 r4/.hg/last-message.txt
302 2 r4/.hg/last-message.txt
303 2 r4/.hg/requires
303 2 r4/.hg/requires
304 2 r4/.hg/store/00changelog.i
304 2 r4/.hg/store/00changelog.i
305 2 r4/.hg/store/00manifest.i
305 2 r4/.hg/store/00manifest.i
306 2 r4/.hg/store/data/d1/f2.d
306 2 r4/.hg/store/data/d1/f2.d
307 2 r4/.hg/store/data/d1/f2.i
307 2 r4/.hg/store/data/d1/f2.i
308 2 r4/.hg/store/data/f1.i
308 2 r4/.hg/store/data/f1.i
309 2 r4/.hg/store/data/f3.i
309 2 r4/.hg/store/data/f3.i
310 2 r4/.hg/store/fncache
310 2 r4/.hg/store/fncache
311 2 r4/.hg/store/phaseroots
311 2 r4/.hg/store/phaseroots
312 2 r4/.hg/store/undo
312 2 r4/.hg/store/undo
313 2 r4/.hg/store/undo.backup.fncache (repofncache !)
313 2 r4/.hg/store/undo.backup.fncache (repofncache !)
314 2 r4/.hg/store/undo.backup.phaseroots
314 2 r4/.hg/store/undo.backup.phaseroots
315 2 r4/.hg/store/undo.backupfiles
315 2 r4/.hg/store/undo.backupfiles
316 2 r4/.hg/store/undo.phaseroots
316 2 r4/.hg/store/undo.phaseroots
317 [24] r4/\.hg/undo\.backup\.dirstate (re)
317 [24] r4/\.hg/undo\.backup\.dirstate (re)
318 2 r4/.hg/undo.bookmarks
318 2 r4/.hg/undo.bookmarks
319 2 r4/.hg/undo.branch
319 2 r4/.hg/undo.branch
320 2 r4/.hg/undo.desc
320 2 r4/.hg/undo.desc
321 [24] r4/\.hg/undo\.dirstate (re)
321 [24] r4/\.hg/undo\.dirstate (re)
322 2 r4/d1/data1
322 2 r4/d1/data1
323 2 r4/d1/f2
323 2 r4/d1/f2
324 1 r4/f1
324 1 r4/f1
325 1 r4/f3 (execbit !)
325 1 r4/f3 (execbit !)
326 2 r4/f3 (no-execbit !)
326 2 r4/f3 (no-execbit !)
327
327
328 #if hardlink-whitelisted
328 #if hardlink-whitelisted
329 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
329 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
330 4 r4/.hg/undo.backup.dirstate
330 4 r4/.hg/undo.backup.dirstate
331 4 r4/.hg/undo.dirstate
331 4 r4/.hg/undo.dirstate
332 #endif
332 #endif
333
333
334 Test hardlinking outside hg:
334 Test hardlinking outside hg:
335
335
336 $ mkdir x
336 $ mkdir x
337 $ echo foo > x/a
337 $ echo foo > x/a
338
338
339 $ linkcp x y
339 $ linkcp x y
340 $ echo bar >> y/a
340 $ echo bar >> y/a
341
341
342 No diff if hardlink:
342 No diff if hardlink:
343
343
344 $ diff x/a y/a
344 $ diff x/a y/a
345
345
346 Test mq hardlinking:
346 Test mq hardlinking:
347
347
348 $ echo "[extensions]" >> $HGRCPATH
348 $ echo "[extensions]" >> $HGRCPATH
349 $ echo "mq=" >> $HGRCPATH
349 $ echo "mq=" >> $HGRCPATH
350
350
351 $ hg init a
351 $ hg init a
352 $ cd a
352 $ cd a
353
353
354 $ hg qimport -n foo - << EOF
354 $ hg qimport -n foo - << EOF
355 > # HG changeset patch
355 > # HG changeset patch
356 > # Date 1 0
356 > # Date 1 0
357 > diff -r 2588a8b53d66 a
357 > diff -r 2588a8b53d66 a
358 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
358 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
359 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
359 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
360 > @@ -0,0 +1,1 @@
360 > @@ -0,0 +1,1 @@
361 > +a
361 > +a
362 > EOF
362 > EOF
363 adding foo to series file
363 adding foo to series file
364
364
365 $ hg qpush
365 $ hg qpush
366 applying foo
366 applying foo
367 now at: foo
367 now at: foo
368
368
369 $ cd ..
369 $ cd ..
370 $ linkcp a b
370 $ linkcp a b
371 $ cd b
371 $ cd b
372
372
373 $ hg qimport -n bar - << EOF
373 $ hg qimport -n bar - << EOF
374 > # HG changeset patch
374 > # HG changeset patch
375 > # Date 2 0
375 > # Date 2 0
376 > diff -r 2588a8b53d66 a
376 > diff -r 2588a8b53d66 a
377 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
377 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
378 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
378 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
379 > @@ -0,0 +1,1 @@
379 > @@ -0,0 +1,1 @@
380 > +b
380 > +b
381 > EOF
381 > EOF
382 adding bar to series file
382 adding bar to series file
383
383
384 $ hg qpush
384 $ hg qpush
385 applying bar
385 applying bar
386 now at: bar
386 now at: bar
387
387
388 $ cat .hg/patches/status
388 $ cat .hg/patches/status
389 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
389 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
390 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
390 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
391
391
392 $ cat .hg/patches/series
392 $ cat .hg/patches/series
393 foo
393 foo
394 bar
394 bar
395
395
396 $ cat ../a/.hg/patches/status
396 $ cat ../a/.hg/patches/status
397 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
397 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
398
398
399 $ cat ../a/.hg/patches/series
399 $ cat ../a/.hg/patches/series
400 foo
400 foo
401
401
402 Test tags hardlinking:
402 Test tags hardlinking:
403
403
404 $ hg qdel -r qbase:qtip
404 $ hg qdel -r qbase:qtip
405 patch foo finalized without changeset message
405 patch foo finalized without changeset message
406 patch bar finalized without changeset message
406 patch bar finalized without changeset message
407
407
408 $ hg tag -l lfoo
408 $ hg tag -l lfoo
409 $ hg tag foo
409 $ hg tag foo
410
410
411 $ cd ..
411 $ cd ..
412 $ linkcp b c
412 $ linkcp b c
413 $ cd c
413 $ cd c
414
414
415 $ hg tag -l -r 0 lbar
415 $ hg tag -l -r 0 lbar
416 $ hg tag -r 0 bar
416 $ hg tag -r 0 bar
417
417
418 $ cat .hgtags
418 $ cat .hgtags
419 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
419 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
420 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
420 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
421
421
422 $ cat .hg/localtags
422 $ cat .hg/localtags
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
424 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
424 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
425
425
426 $ cat ../b/.hgtags
426 $ cat ../b/.hgtags
427 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
427 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
428
428
429 $ cat ../b/.hg/localtags
429 $ cat ../b/.hg/localtags
430 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
430 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
431
431
432 $ cd ..
432 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now