##// END OF EJS Templates
clone: explicitly push bookmarks when cloning from local to remote...
Pierre-Yves David -
r22647:5b6cd852 default
parent child Browse files
Show More
@@ -1,684 +1,685 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 i18n import _
9 from i18n import _
10 from lock import release
10 from lock import release
11 from node import hex, nullid
11 from node import hex, nullid
12 import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo
12 import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo
13 import bookmarks, lock, util, extensions, error, node, scmutil, phases, url
13 import bookmarks, lock, util, extensions, error, node, scmutil, phases, url
14 import cmdutil, discovery, repoview, exchange
14 import cmdutil, discovery, repoview, exchange
15 import merge as mergemod
15 import merge as mergemod
16 import verify as verifymod
16 import verify as verifymod
17 import errno, os, shutil
17 import errno, os, shutil
18
18
19 def _local(path):
19 def _local(path):
20 path = util.expandpath(util.urllocalpath(path))
20 path = util.expandpath(util.urllocalpath(path))
21 return (os.path.isfile(path) and bundlerepo or localrepo)
21 return (os.path.isfile(path) and bundlerepo or localrepo)
22
22
23 def addbranchrevs(lrepo, other, branches, revs):
23 def addbranchrevs(lrepo, other, branches, revs):
24 peer = other.peer() # a courtesy to callers using a localrepo for other
24 peer = other.peer() # a courtesy to callers using a localrepo for other
25 hashbranch, branches = branches
25 hashbranch, branches = branches
26 if not hashbranch and not branches:
26 if not hashbranch and not branches:
27 return revs or None, revs and revs[0] or None
27 return revs or None, revs and revs[0] or None
28 revs = revs and list(revs) or []
28 revs = revs and list(revs) or []
29 if not peer.capable('branchmap'):
29 if not peer.capable('branchmap'):
30 if branches:
30 if branches:
31 raise util.Abort(_("remote branch lookup not supported"))
31 raise util.Abort(_("remote branch lookup not supported"))
32 revs.append(hashbranch)
32 revs.append(hashbranch)
33 return revs, revs[0]
33 return revs, revs[0]
34 branchmap = peer.branchmap()
34 branchmap = peer.branchmap()
35
35
36 def primary(branch):
36 def primary(branch):
37 if branch == '.':
37 if branch == '.':
38 if not lrepo:
38 if not lrepo:
39 raise util.Abort(_("dirstate branch not accessible"))
39 raise util.Abort(_("dirstate branch not accessible"))
40 branch = lrepo.dirstate.branch()
40 branch = lrepo.dirstate.branch()
41 if branch in branchmap:
41 if branch in branchmap:
42 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
42 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
43 return True
43 return True
44 else:
44 else:
45 return False
45 return False
46
46
47 for branch in branches:
47 for branch in branches:
48 if not primary(branch):
48 if not primary(branch):
49 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
49 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
50 if hashbranch:
50 if hashbranch:
51 if not primary(hashbranch):
51 if not primary(hashbranch):
52 revs.append(hashbranch)
52 revs.append(hashbranch)
53 return revs, revs[0]
53 return revs, revs[0]
54
54
55 def parseurl(path, branches=None):
55 def parseurl(path, branches=None):
56 '''parse url#branch, returning (url, (branch, branches))'''
56 '''parse url#branch, returning (url, (branch, branches))'''
57
57
58 u = util.url(path)
58 u = util.url(path)
59 branch = None
59 branch = None
60 if u.fragment:
60 if u.fragment:
61 branch = u.fragment
61 branch = u.fragment
62 u.fragment = None
62 u.fragment = None
63 return str(u), (branch, branches or [])
63 return str(u), (branch, branches or [])
64
64
65 schemes = {
65 schemes = {
66 'bundle': bundlerepo,
66 'bundle': bundlerepo,
67 'union': unionrepo,
67 'union': unionrepo,
68 'file': _local,
68 'file': _local,
69 'http': httppeer,
69 'http': httppeer,
70 'https': httppeer,
70 'https': httppeer,
71 'ssh': sshpeer,
71 'ssh': sshpeer,
72 'static-http': statichttprepo,
72 'static-http': statichttprepo,
73 }
73 }
74
74
75 def _peerlookup(path):
75 def _peerlookup(path):
76 u = util.url(path)
76 u = util.url(path)
77 scheme = u.scheme or 'file'
77 scheme = u.scheme or 'file'
78 thing = schemes.get(scheme) or schemes['file']
78 thing = schemes.get(scheme) or schemes['file']
79 try:
79 try:
80 return thing(path)
80 return thing(path)
81 except TypeError:
81 except TypeError:
82 return thing
82 return thing
83
83
84 def islocal(repo):
84 def islocal(repo):
85 '''return true if repo (or path pointing to repo) is local'''
85 '''return true if repo (or path pointing to repo) is local'''
86 if isinstance(repo, str):
86 if isinstance(repo, str):
87 try:
87 try:
88 return _peerlookup(repo).islocal(repo)
88 return _peerlookup(repo).islocal(repo)
89 except AttributeError:
89 except AttributeError:
90 return False
90 return False
91 return repo.local()
91 return repo.local()
92
92
93 def openpath(ui, path):
93 def openpath(ui, path):
94 '''open path with open if local, url.open if remote'''
94 '''open path with open if local, url.open if remote'''
95 pathurl = util.url(path, parsequery=False, parsefragment=False)
95 pathurl = util.url(path, parsequery=False, parsefragment=False)
96 if pathurl.islocal():
96 if pathurl.islocal():
97 return util.posixfile(pathurl.localpath(), 'rb')
97 return util.posixfile(pathurl.localpath(), 'rb')
98 else:
98 else:
99 return url.open(ui, path)
99 return url.open(ui, path)
100
100
101 # a list of (ui, repo) functions called for wire peer initialization
101 # a list of (ui, repo) functions called for wire peer initialization
102 wirepeersetupfuncs = []
102 wirepeersetupfuncs = []
103
103
104 def _peerorrepo(ui, path, create=False):
104 def _peerorrepo(ui, path, create=False):
105 """return a repository object for the specified path"""
105 """return a repository object for the specified path"""
106 obj = _peerlookup(path).instance(ui, path, create)
106 obj = _peerlookup(path).instance(ui, path, create)
107 ui = getattr(obj, "ui", ui)
107 ui = getattr(obj, "ui", ui)
108 for name, module in extensions.extensions(ui):
108 for name, module in extensions.extensions(ui):
109 hook = getattr(module, 'reposetup', None)
109 hook = getattr(module, 'reposetup', None)
110 if hook:
110 if hook:
111 hook(ui, obj)
111 hook(ui, obj)
112 if not obj.local():
112 if not obj.local():
113 for f in wirepeersetupfuncs:
113 for f in wirepeersetupfuncs:
114 f(ui, obj)
114 f(ui, obj)
115 return obj
115 return obj
116
116
117 def repository(ui, path='', create=False):
117 def repository(ui, path='', create=False):
118 """return a repository object for the specified path"""
118 """return a repository object for the specified path"""
119 peer = _peerorrepo(ui, path, create)
119 peer = _peerorrepo(ui, path, create)
120 repo = peer.local()
120 repo = peer.local()
121 if not repo:
121 if not repo:
122 raise util.Abort(_("repository '%s' is not local") %
122 raise util.Abort(_("repository '%s' is not local") %
123 (path or peer.url()))
123 (path or peer.url()))
124 return repo.filtered('visible')
124 return repo.filtered('visible')
125
125
126 def peer(uiorrepo, opts, path, create=False):
126 def peer(uiorrepo, opts, path, create=False):
127 '''return a repository peer for the specified path'''
127 '''return a repository peer for the specified path'''
128 rui = remoteui(uiorrepo, opts)
128 rui = remoteui(uiorrepo, opts)
129 return _peerorrepo(rui, path, create).peer()
129 return _peerorrepo(rui, path, create).peer()
130
130
131 def defaultdest(source):
131 def defaultdest(source):
132 '''return default destination of clone if none is given
132 '''return default destination of clone if none is given
133
133
134 >>> defaultdest('foo')
134 >>> defaultdest('foo')
135 'foo'
135 'foo'
136 >>> defaultdest('/foo/bar')
136 >>> defaultdest('/foo/bar')
137 'bar'
137 'bar'
138 >>> defaultdest('/')
138 >>> defaultdest('/')
139 ''
139 ''
140 >>> defaultdest('')
140 >>> defaultdest('')
141 ''
141 ''
142 >>> defaultdest('http://example.org/')
142 >>> defaultdest('http://example.org/')
143 ''
143 ''
144 >>> defaultdest('http://example.org/foo/')
144 >>> defaultdest('http://example.org/foo/')
145 'foo'
145 'foo'
146 '''
146 '''
147 path = util.url(source).path
147 path = util.url(source).path
148 if not path:
148 if not path:
149 return ''
149 return ''
150 return os.path.basename(os.path.normpath(path))
150 return os.path.basename(os.path.normpath(path))
151
151
152 def share(ui, source, dest=None, update=True):
152 def share(ui, source, dest=None, update=True):
153 '''create a shared repository'''
153 '''create a shared repository'''
154
154
155 if not islocal(source):
155 if not islocal(source):
156 raise util.Abort(_('can only share local repositories'))
156 raise util.Abort(_('can only share local repositories'))
157
157
158 if not dest:
158 if not dest:
159 dest = defaultdest(source)
159 dest = defaultdest(source)
160 else:
160 else:
161 dest = ui.expandpath(dest)
161 dest = ui.expandpath(dest)
162
162
163 if isinstance(source, str):
163 if isinstance(source, str):
164 origsource = ui.expandpath(source)
164 origsource = ui.expandpath(source)
165 source, branches = parseurl(origsource)
165 source, branches = parseurl(origsource)
166 srcrepo = repository(ui, source)
166 srcrepo = repository(ui, source)
167 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
167 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
168 else:
168 else:
169 srcrepo = source.local()
169 srcrepo = source.local()
170 origsource = source = srcrepo.url()
170 origsource = source = srcrepo.url()
171 checkout = None
171 checkout = None
172
172
173 sharedpath = srcrepo.sharedpath # if our source is already sharing
173 sharedpath = srcrepo.sharedpath # if our source is already sharing
174
174
175 destwvfs = scmutil.vfs(dest, realpath=True)
175 destwvfs = scmutil.vfs(dest, realpath=True)
176 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
176 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
177
177
178 if destvfs.lexists():
178 if destvfs.lexists():
179 raise util.Abort(_('destination already exists'))
179 raise util.Abort(_('destination already exists'))
180
180
181 if not destwvfs.isdir():
181 if not destwvfs.isdir():
182 destwvfs.mkdir()
182 destwvfs.mkdir()
183 destvfs.makedir()
183 destvfs.makedir()
184
184
185 requirements = ''
185 requirements = ''
186 try:
186 try:
187 requirements = srcrepo.opener.read('requires')
187 requirements = srcrepo.opener.read('requires')
188 except IOError, inst:
188 except IOError, inst:
189 if inst.errno != errno.ENOENT:
189 if inst.errno != errno.ENOENT:
190 raise
190 raise
191
191
192 requirements += 'shared\n'
192 requirements += 'shared\n'
193 destvfs.write('requires', requirements)
193 destvfs.write('requires', requirements)
194 destvfs.write('sharedpath', sharedpath)
194 destvfs.write('sharedpath', sharedpath)
195
195
196 r = repository(ui, destwvfs.base)
196 r = repository(ui, destwvfs.base)
197
197
198 default = srcrepo.ui.config('paths', 'default')
198 default = srcrepo.ui.config('paths', 'default')
199 if default:
199 if default:
200 fp = r.opener("hgrc", "w", text=True)
200 fp = r.opener("hgrc", "w", text=True)
201 fp.write("[paths]\n")
201 fp.write("[paths]\n")
202 fp.write("default = %s\n" % default)
202 fp.write("default = %s\n" % default)
203 fp.close()
203 fp.close()
204
204
205 if update:
205 if update:
206 r.ui.status(_("updating working directory\n"))
206 r.ui.status(_("updating working directory\n"))
207 if update is not True:
207 if update is not True:
208 checkout = update
208 checkout = update
209 for test in (checkout, 'default', 'tip'):
209 for test in (checkout, 'default', 'tip'):
210 if test is None:
210 if test is None:
211 continue
211 continue
212 try:
212 try:
213 uprev = r.lookup(test)
213 uprev = r.lookup(test)
214 break
214 break
215 except error.RepoLookupError:
215 except error.RepoLookupError:
216 continue
216 continue
217 _update(r, uprev)
217 _update(r, uprev)
218
218
219 def copystore(ui, srcrepo, destpath):
219 def copystore(ui, srcrepo, destpath):
220 '''copy files from store of srcrepo in destpath
220 '''copy files from store of srcrepo in destpath
221
221
222 returns destlock
222 returns destlock
223 '''
223 '''
224 destlock = None
224 destlock = None
225 try:
225 try:
226 hardlink = None
226 hardlink = None
227 num = 0
227 num = 0
228 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
228 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
229 srcvfs = scmutil.vfs(srcrepo.sharedpath)
229 srcvfs = scmutil.vfs(srcrepo.sharedpath)
230 dstvfs = scmutil.vfs(destpath)
230 dstvfs = scmutil.vfs(destpath)
231 for f in srcrepo.store.copylist():
231 for f in srcrepo.store.copylist():
232 if srcpublishing and f.endswith('phaseroots'):
232 if srcpublishing and f.endswith('phaseroots'):
233 continue
233 continue
234 dstbase = os.path.dirname(f)
234 dstbase = os.path.dirname(f)
235 if dstbase and not dstvfs.exists(dstbase):
235 if dstbase and not dstvfs.exists(dstbase):
236 dstvfs.mkdir(dstbase)
236 dstvfs.mkdir(dstbase)
237 if srcvfs.exists(f):
237 if srcvfs.exists(f):
238 if f.endswith('data'):
238 if f.endswith('data'):
239 # 'dstbase' may be empty (e.g. revlog format 0)
239 # 'dstbase' may be empty (e.g. revlog format 0)
240 lockfile = os.path.join(dstbase, "lock")
240 lockfile = os.path.join(dstbase, "lock")
241 # lock to avoid premature writing to the target
241 # lock to avoid premature writing to the target
242 destlock = lock.lock(dstvfs, lockfile)
242 destlock = lock.lock(dstvfs, lockfile)
243 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
243 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
244 hardlink)
244 hardlink)
245 num += n
245 num += n
246 if hardlink:
246 if hardlink:
247 ui.debug("linked %d files\n" % num)
247 ui.debug("linked %d files\n" % num)
248 else:
248 else:
249 ui.debug("copied %d files\n" % num)
249 ui.debug("copied %d files\n" % num)
250 return destlock
250 return destlock
251 except: # re-raises
251 except: # re-raises
252 release(destlock)
252 release(destlock)
253 raise
253 raise
254
254
255 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
255 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
256 update=True, stream=False, branch=None):
256 update=True, stream=False, branch=None):
257 """Make a copy of an existing repository.
257 """Make a copy of an existing repository.
258
258
259 Create a copy of an existing repository in a new directory. The
259 Create a copy of an existing repository in a new directory. The
260 source and destination are URLs, as passed to the repository
260 source and destination are URLs, as passed to the repository
261 function. Returns a pair of repository peers, the source and
261 function. Returns a pair of repository peers, the source and
262 newly created destination.
262 newly created destination.
263
263
264 The location of the source is added to the new repository's
264 The location of the source is added to the new repository's
265 .hg/hgrc file, as the default to be used for future pulls and
265 .hg/hgrc file, as the default to be used for future pulls and
266 pushes.
266 pushes.
267
267
268 If an exception is raised, the partly cloned/updated destination
268 If an exception is raised, the partly cloned/updated destination
269 repository will be deleted.
269 repository will be deleted.
270
270
271 Arguments:
271 Arguments:
272
272
273 source: repository object or URL
273 source: repository object or URL
274
274
275 dest: URL of destination repository to create (defaults to base
275 dest: URL of destination repository to create (defaults to base
276 name of source repository)
276 name of source repository)
277
277
278 pull: always pull from source repository, even in local case
278 pull: always pull from source repository, even in local case
279
279
280 stream: stream raw data uncompressed from repository (fast over
280 stream: stream raw data uncompressed from repository (fast over
281 LAN, slow over WAN)
281 LAN, slow over WAN)
282
282
283 rev: revision to clone up to (implies pull=True)
283 rev: revision to clone up to (implies pull=True)
284
284
285 update: update working directory after clone completes, if
285 update: update working directory after clone completes, if
286 destination is local repository (True means update to default rev,
286 destination is local repository (True means update to default rev,
287 anything else is treated as a revision)
287 anything else is treated as a revision)
288
288
289 branch: branches to clone
289 branch: branches to clone
290 """
290 """
291
291
292 if isinstance(source, str):
292 if isinstance(source, str):
293 origsource = ui.expandpath(source)
293 origsource = ui.expandpath(source)
294 source, branch = parseurl(origsource, branch)
294 source, branch = parseurl(origsource, branch)
295 srcpeer = peer(ui, peeropts, source)
295 srcpeer = peer(ui, peeropts, source)
296 else:
296 else:
297 srcpeer = source.peer() # in case we were called with a localrepo
297 srcpeer = source.peer() # in case we were called with a localrepo
298 branch = (None, branch or [])
298 branch = (None, branch or [])
299 origsource = source = srcpeer.url()
299 origsource = source = srcpeer.url()
300 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
300 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
301
301
302 if dest is None:
302 if dest is None:
303 dest = defaultdest(source)
303 dest = defaultdest(source)
304 if dest:
304 if dest:
305 ui.status(_("destination directory: %s\n") % dest)
305 ui.status(_("destination directory: %s\n") % dest)
306 else:
306 else:
307 dest = ui.expandpath(dest)
307 dest = ui.expandpath(dest)
308
308
309 dest = util.urllocalpath(dest)
309 dest = util.urllocalpath(dest)
310 source = util.urllocalpath(source)
310 source = util.urllocalpath(source)
311
311
312 if not dest:
312 if not dest:
313 raise util.Abort(_("empty destination path is not valid"))
313 raise util.Abort(_("empty destination path is not valid"))
314
314
315 destvfs = scmutil.vfs(dest, expandpath=True)
315 destvfs = scmutil.vfs(dest, expandpath=True)
316 if destvfs.lexists():
316 if destvfs.lexists():
317 if not destvfs.isdir():
317 if not destvfs.isdir():
318 raise util.Abort(_("destination '%s' already exists") % dest)
318 raise util.Abort(_("destination '%s' already exists") % dest)
319 elif destvfs.listdir():
319 elif destvfs.listdir():
320 raise util.Abort(_("destination '%s' is not empty") % dest)
320 raise util.Abort(_("destination '%s' is not empty") % dest)
321
321
322 srclock = destlock = cleandir = None
322 srclock = destlock = cleandir = None
323 srcrepo = srcpeer.local()
323 srcrepo = srcpeer.local()
324 try:
324 try:
325 abspath = origsource
325 abspath = origsource
326 if islocal(origsource):
326 if islocal(origsource):
327 abspath = os.path.abspath(util.urllocalpath(origsource))
327 abspath = os.path.abspath(util.urllocalpath(origsource))
328
328
329 if islocal(dest):
329 if islocal(dest):
330 cleandir = dest
330 cleandir = dest
331
331
332 copy = False
332 copy = False
333 if (srcrepo and srcrepo.cancopy() and islocal(dest)
333 if (srcrepo and srcrepo.cancopy() and islocal(dest)
334 and not phases.hassecret(srcrepo)):
334 and not phases.hassecret(srcrepo)):
335 copy = not pull and not rev
335 copy = not pull and not rev
336
336
337 if copy:
337 if copy:
338 try:
338 try:
339 # we use a lock here because if we race with commit, we
339 # we use a lock here because if we race with commit, we
340 # can end up with extra data in the cloned revlogs that's
340 # can end up with extra data in the cloned revlogs that's
341 # not pointed to by changesets, thus causing verify to
341 # not pointed to by changesets, thus causing verify to
342 # fail
342 # fail
343 srclock = srcrepo.lock(wait=False)
343 srclock = srcrepo.lock(wait=False)
344 except error.LockError:
344 except error.LockError:
345 copy = False
345 copy = False
346
346
347 if copy:
347 if copy:
348 srcrepo.hook('preoutgoing', throw=True, source='clone')
348 srcrepo.hook('preoutgoing', throw=True, source='clone')
349 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
349 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
350 if not os.path.exists(dest):
350 if not os.path.exists(dest):
351 os.mkdir(dest)
351 os.mkdir(dest)
352 else:
352 else:
353 # only clean up directories we create ourselves
353 # only clean up directories we create ourselves
354 cleandir = hgdir
354 cleandir = hgdir
355 try:
355 try:
356 destpath = hgdir
356 destpath = hgdir
357 util.makedir(destpath, notindexed=True)
357 util.makedir(destpath, notindexed=True)
358 except OSError, inst:
358 except OSError, inst:
359 if inst.errno == errno.EEXIST:
359 if inst.errno == errno.EEXIST:
360 cleandir = None
360 cleandir = None
361 raise util.Abort(_("destination '%s' already exists")
361 raise util.Abort(_("destination '%s' already exists")
362 % dest)
362 % dest)
363 raise
363 raise
364
364
365 destlock = copystore(ui, srcrepo, destpath)
365 destlock = copystore(ui, srcrepo, destpath)
366 # copy bookmarks over
366 # copy bookmarks over
367 srcbookmarks = srcrepo.join('bookmarks')
367 srcbookmarks = srcrepo.join('bookmarks')
368 dstbookmarks = os.path.join(destpath, 'bookmarks')
368 dstbookmarks = os.path.join(destpath, 'bookmarks')
369 if os.path.exists(srcbookmarks):
369 if os.path.exists(srcbookmarks):
370 util.copyfile(srcbookmarks, dstbookmarks)
370 util.copyfile(srcbookmarks, dstbookmarks)
371
371
372 # Recomputing branch cache might be slow on big repos,
372 # Recomputing branch cache might be slow on big repos,
373 # so just copy it
373 # so just copy it
374 def copybranchcache(fname):
374 def copybranchcache(fname):
375 srcbranchcache = srcrepo.join('cache/%s' % fname)
375 srcbranchcache = srcrepo.join('cache/%s' % fname)
376 dstbranchcache = os.path.join(dstcachedir, fname)
376 dstbranchcache = os.path.join(dstcachedir, fname)
377 if os.path.exists(srcbranchcache):
377 if os.path.exists(srcbranchcache):
378 if not os.path.exists(dstcachedir):
378 if not os.path.exists(dstcachedir):
379 os.mkdir(dstcachedir)
379 os.mkdir(dstcachedir)
380 util.copyfile(srcbranchcache, dstbranchcache)
380 util.copyfile(srcbranchcache, dstbranchcache)
381
381
382 dstcachedir = os.path.join(destpath, 'cache')
382 dstcachedir = os.path.join(destpath, 'cache')
383 # In local clones we're copying all nodes, not just served
383 # In local clones we're copying all nodes, not just served
384 # ones. Therefore copy all branchcaches over.
384 # ones. Therefore copy all branchcaches over.
385 copybranchcache('branch2')
385 copybranchcache('branch2')
386 for cachename in repoview.filtertable:
386 for cachename in repoview.filtertable:
387 copybranchcache('branch2-%s' % cachename)
387 copybranchcache('branch2-%s' % cachename)
388
388
389 # we need to re-init the repo after manually copying the data
389 # we need to re-init the repo after manually copying the data
390 # into it
390 # into it
391 destpeer = peer(srcrepo, peeropts, dest)
391 destpeer = peer(srcrepo, peeropts, dest)
392 srcrepo.hook('outgoing', source='clone',
392 srcrepo.hook('outgoing', source='clone',
393 node=node.hex(node.nullid))
393 node=node.hex(node.nullid))
394 else:
394 else:
395 try:
395 try:
396 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
396 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
397 # only pass ui when no srcrepo
397 # only pass ui when no srcrepo
398 except OSError, inst:
398 except OSError, inst:
399 if inst.errno == errno.EEXIST:
399 if inst.errno == errno.EEXIST:
400 cleandir = None
400 cleandir = None
401 raise util.Abort(_("destination '%s' already exists")
401 raise util.Abort(_("destination '%s' already exists")
402 % dest)
402 % dest)
403 raise
403 raise
404
404
405 revs = None
405 revs = None
406 if rev:
406 if rev:
407 if not srcpeer.capable('lookup'):
407 if not srcpeer.capable('lookup'):
408 raise util.Abort(_("src repository does not support "
408 raise util.Abort(_("src repository does not support "
409 "revision lookup and so doesn't "
409 "revision lookup and so doesn't "
410 "support clone by revision"))
410 "support clone by revision"))
411 revs = [srcpeer.lookup(r) for r in rev]
411 revs = [srcpeer.lookup(r) for r in rev]
412 checkout = revs[0]
412 checkout = revs[0]
413 if destpeer.local():
413 if destpeer.local():
414 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
414 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
415 elif srcrepo:
415 elif srcrepo:
416 exchange.push(srcrepo, destpeer, revs=revs)
416 exchange.push(srcrepo, destpeer, revs=revs,
417 bookmarks=srcrepo._bookmarks.keys())
417 else:
418 else:
418 raise util.Abort(_("clone from remote to remote not supported"))
419 raise util.Abort(_("clone from remote to remote not supported"))
419
420
420 cleandir = None
421 cleandir = None
421
422
422 # clone all bookmarks except divergent ones
423 # clone all bookmarks except divergent ones
423 destrepo = destpeer.local()
424 destrepo = destpeer.local()
424 if destrepo and srcpeer.capable("pushkey"):
425 if destrepo and srcpeer.capable("pushkey"):
425 rb = srcpeer.listkeys('bookmarks')
426 rb = srcpeer.listkeys('bookmarks')
426 marks = destrepo._bookmarks
427 marks = destrepo._bookmarks
427 for k, n in rb.iteritems():
428 for k, n in rb.iteritems():
428 try:
429 try:
429 m = destrepo.lookup(n)
430 m = destrepo.lookup(n)
430 marks[k] = m
431 marks[k] = m
431 except error.RepoLookupError:
432 except error.RepoLookupError:
432 pass
433 pass
433 if rb:
434 if rb:
434 marks.write()
435 marks.write()
435 elif srcrepo and destpeer.capable("pushkey"):
436 elif srcrepo and destpeer.capable("pushkey"):
436 for k, n in srcrepo._bookmarks.iteritems():
437 for k, n in srcrepo._bookmarks.iteritems():
437 destpeer.pushkey('bookmarks', k, '', hex(n))
438 destpeer.pushkey('bookmarks', k, '', hex(n))
438
439
439 if destrepo:
440 if destrepo:
440 template = (
441 template = (
441 '# You may want to set your username here if it is not set\n'
442 '# You may want to set your username here if it is not set\n'
442 "# globally, or this repository requires a different\n"
443 "# globally, or this repository requires a different\n"
443 '# username from your usual configuration. If you want to\n'
444 '# username from your usual configuration. If you want to\n'
444 '# set something for all of your repositories on this\n'
445 '# set something for all of your repositories on this\n'
445 '# computer, try running the command\n'
446 '# computer, try running the command\n'
446 "# 'hg config --edit --global'\n"
447 "# 'hg config --edit --global'\n"
447 '# [ui]\n'
448 '# [ui]\n'
448 '# username = Jane Doe <jdoe@example.com>\n'
449 '# username = Jane Doe <jdoe@example.com>\n'
449 '[paths]\n'
450 '[paths]\n'
450 'default = %s\n'
451 'default = %s\n'
451 )
452 )
452 fp = destrepo.opener("hgrc", "w", text=True)
453 fp = destrepo.opener("hgrc", "w", text=True)
453 u = util.url(abspath)
454 u = util.url(abspath)
454 u.passwd = None
455 u.passwd = None
455 defaulturl = str(u)
456 defaulturl = str(u)
456 fp.write(template % defaulturl)
457 fp.write(template % defaulturl)
457 fp.close()
458 fp.close()
458
459
459 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
460 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
460
461
461 if update:
462 if update:
462 if update is not True:
463 if update is not True:
463 checkout = srcpeer.lookup(update)
464 checkout = srcpeer.lookup(update)
464 uprev = None
465 uprev = None
465 status = None
466 status = None
466 if checkout is not None:
467 if checkout is not None:
467 try:
468 try:
468 uprev = destrepo.lookup(checkout)
469 uprev = destrepo.lookup(checkout)
469 except error.RepoLookupError:
470 except error.RepoLookupError:
470 pass
471 pass
471 if uprev is None:
472 if uprev is None:
472 try:
473 try:
473 uprev = destrepo._bookmarks['@']
474 uprev = destrepo._bookmarks['@']
474 update = '@'
475 update = '@'
475 bn = destrepo[uprev].branch()
476 bn = destrepo[uprev].branch()
476 if bn == 'default':
477 if bn == 'default':
477 status = _("updating to bookmark @\n")
478 status = _("updating to bookmark @\n")
478 else:
479 else:
479 status = (_("updating to bookmark @ on branch %s\n")
480 status = (_("updating to bookmark @ on branch %s\n")
480 % bn)
481 % bn)
481 except KeyError:
482 except KeyError:
482 try:
483 try:
483 uprev = destrepo.branchtip('default')
484 uprev = destrepo.branchtip('default')
484 except error.RepoLookupError:
485 except error.RepoLookupError:
485 uprev = destrepo.lookup('tip')
486 uprev = destrepo.lookup('tip')
486 if not status:
487 if not status:
487 bn = destrepo[uprev].branch()
488 bn = destrepo[uprev].branch()
488 status = _("updating to branch %s\n") % bn
489 status = _("updating to branch %s\n") % bn
489 destrepo.ui.status(status)
490 destrepo.ui.status(status)
490 _update(destrepo, uprev)
491 _update(destrepo, uprev)
491 if update in destrepo._bookmarks:
492 if update in destrepo._bookmarks:
492 bookmarks.setcurrent(destrepo, update)
493 bookmarks.setcurrent(destrepo, update)
493 finally:
494 finally:
494 release(srclock, destlock)
495 release(srclock, destlock)
495 if cleandir is not None:
496 if cleandir is not None:
496 shutil.rmtree(cleandir, True)
497 shutil.rmtree(cleandir, True)
497 if srcpeer is not None:
498 if srcpeer is not None:
498 srcpeer.close()
499 srcpeer.close()
499 return srcpeer, destpeer
500 return srcpeer, destpeer
500
501
501 def _showstats(repo, stats):
502 def _showstats(repo, stats):
502 repo.ui.status(_("%d files updated, %d files merged, "
503 repo.ui.status(_("%d files updated, %d files merged, "
503 "%d files removed, %d files unresolved\n") % stats)
504 "%d files removed, %d files unresolved\n") % stats)
504
505
505 def updaterepo(repo, node, overwrite):
506 def updaterepo(repo, node, overwrite):
506 """Update the working directory to node.
507 """Update the working directory to node.
507
508
508 When overwrite is set, changes are clobbered, merged else
509 When overwrite is set, changes are clobbered, merged else
509
510
510 returns stats (see pydoc mercurial.merge.applyupdates)"""
511 returns stats (see pydoc mercurial.merge.applyupdates)"""
511 return mergemod.update(repo, node, False, overwrite, None,
512 return mergemod.update(repo, node, False, overwrite, None,
512 labels=['working copy', 'destination'])
513 labels=['working copy', 'destination'])
513
514
514 def update(repo, node):
515 def update(repo, node):
515 """update the working directory to node, merging linear changes"""
516 """update the working directory to node, merging linear changes"""
516 stats = updaterepo(repo, node, False)
517 stats = updaterepo(repo, node, False)
517 _showstats(repo, stats)
518 _showstats(repo, stats)
518 if stats[3]:
519 if stats[3]:
519 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
520 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
520 return stats[3] > 0
521 return stats[3] > 0
521
522
522 # naming conflict in clone()
523 # naming conflict in clone()
523 _update = update
524 _update = update
524
525
525 def clean(repo, node, show_stats=True):
526 def clean(repo, node, show_stats=True):
526 """forcibly switch the working directory to node, clobbering changes"""
527 """forcibly switch the working directory to node, clobbering changes"""
527 stats = updaterepo(repo, node, True)
528 stats = updaterepo(repo, node, True)
528 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
529 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
529 if show_stats:
530 if show_stats:
530 _showstats(repo, stats)
531 _showstats(repo, stats)
531 return stats[3] > 0
532 return stats[3] > 0
532
533
533 def merge(repo, node, force=None, remind=True):
534 def merge(repo, node, force=None, remind=True):
534 """Branch merge with node, resolving changes. Return true if any
535 """Branch merge with node, resolving changes. Return true if any
535 unresolved conflicts."""
536 unresolved conflicts."""
536 stats = mergemod.update(repo, node, True, force, False)
537 stats = mergemod.update(repo, node, True, force, False)
537 _showstats(repo, stats)
538 _showstats(repo, stats)
538 if stats[3]:
539 if stats[3]:
539 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
540 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
540 "or 'hg update -C .' to abandon\n"))
541 "or 'hg update -C .' to abandon\n"))
541 elif remind:
542 elif remind:
542 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
543 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
543 return stats[3] > 0
544 return stats[3] > 0
544
545
545 def _incoming(displaychlist, subreporecurse, ui, repo, source,
546 def _incoming(displaychlist, subreporecurse, ui, repo, source,
546 opts, buffered=False):
547 opts, buffered=False):
547 """
548 """
548 Helper for incoming / gincoming.
549 Helper for incoming / gincoming.
549 displaychlist gets called with
550 displaychlist gets called with
550 (remoterepo, incomingchangesetlist, displayer) parameters,
551 (remoterepo, incomingchangesetlist, displayer) parameters,
551 and is supposed to contain only code that can't be unified.
552 and is supposed to contain only code that can't be unified.
552 """
553 """
553 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
554 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
554 other = peer(repo, opts, source)
555 other = peer(repo, opts, source)
555 ui.status(_('comparing with %s\n') % util.hidepassword(source))
556 ui.status(_('comparing with %s\n') % util.hidepassword(source))
556 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
557 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
557
558
558 if revs:
559 if revs:
559 revs = [other.lookup(rev) for rev in revs]
560 revs = [other.lookup(rev) for rev in revs]
560 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
561 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
561 revs, opts["bundle"], opts["force"])
562 revs, opts["bundle"], opts["force"])
562 try:
563 try:
563 if not chlist:
564 if not chlist:
564 ui.status(_("no changes found\n"))
565 ui.status(_("no changes found\n"))
565 return subreporecurse()
566 return subreporecurse()
566
567
567 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
568 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
568 displaychlist(other, chlist, displayer)
569 displaychlist(other, chlist, displayer)
569 displayer.close()
570 displayer.close()
570 finally:
571 finally:
571 cleanupfn()
572 cleanupfn()
572 subreporecurse()
573 subreporecurse()
573 return 0 # exit code is zero since we found incoming changes
574 return 0 # exit code is zero since we found incoming changes
574
575
575 def incoming(ui, repo, source, opts):
576 def incoming(ui, repo, source, opts):
576 def subreporecurse():
577 def subreporecurse():
577 ret = 1
578 ret = 1
578 if opts.get('subrepos'):
579 if opts.get('subrepos'):
579 ctx = repo[None]
580 ctx = repo[None]
580 for subpath in sorted(ctx.substate):
581 for subpath in sorted(ctx.substate):
581 sub = ctx.sub(subpath)
582 sub = ctx.sub(subpath)
582 ret = min(ret, sub.incoming(ui, source, opts))
583 ret = min(ret, sub.incoming(ui, source, opts))
583 return ret
584 return ret
584
585
585 def display(other, chlist, displayer):
586 def display(other, chlist, displayer):
586 limit = cmdutil.loglimit(opts)
587 limit = cmdutil.loglimit(opts)
587 if opts.get('newest_first'):
588 if opts.get('newest_first'):
588 chlist.reverse()
589 chlist.reverse()
589 count = 0
590 count = 0
590 for n in chlist:
591 for n in chlist:
591 if limit is not None and count >= limit:
592 if limit is not None and count >= limit:
592 break
593 break
593 parents = [p for p in other.changelog.parents(n) if p != nullid]
594 parents = [p for p in other.changelog.parents(n) if p != nullid]
594 if opts.get('no_merges') and len(parents) == 2:
595 if opts.get('no_merges') and len(parents) == 2:
595 continue
596 continue
596 count += 1
597 count += 1
597 displayer.show(other[n])
598 displayer.show(other[n])
598 return _incoming(display, subreporecurse, ui, repo, source, opts)
599 return _incoming(display, subreporecurse, ui, repo, source, opts)
599
600
600 def _outgoing(ui, repo, dest, opts):
601 def _outgoing(ui, repo, dest, opts):
601 dest = ui.expandpath(dest or 'default-push', dest or 'default')
602 dest = ui.expandpath(dest or 'default-push', dest or 'default')
602 dest, branches = parseurl(dest, opts.get('branch'))
603 dest, branches = parseurl(dest, opts.get('branch'))
603 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
604 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
604 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
605 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
605 if revs:
606 if revs:
606 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
607 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
607
608
608 other = peer(repo, opts, dest)
609 other = peer(repo, opts, dest)
609 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
610 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
610 force=opts.get('force'))
611 force=opts.get('force'))
611 o = outgoing.missing
612 o = outgoing.missing
612 if not o:
613 if not o:
613 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
614 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
614 return o, other
615 return o, other
615
616
616 def outgoing(ui, repo, dest, opts):
617 def outgoing(ui, repo, dest, opts):
617 def recurse():
618 def recurse():
618 ret = 1
619 ret = 1
619 if opts.get('subrepos'):
620 if opts.get('subrepos'):
620 ctx = repo[None]
621 ctx = repo[None]
621 for subpath in sorted(ctx.substate):
622 for subpath in sorted(ctx.substate):
622 sub = ctx.sub(subpath)
623 sub = ctx.sub(subpath)
623 ret = min(ret, sub.outgoing(ui, dest, opts))
624 ret = min(ret, sub.outgoing(ui, dest, opts))
624 return ret
625 return ret
625
626
626 limit = cmdutil.loglimit(opts)
627 limit = cmdutil.loglimit(opts)
627 o, other = _outgoing(ui, repo, dest, opts)
628 o, other = _outgoing(ui, repo, dest, opts)
628 if not o:
629 if not o:
629 cmdutil.outgoinghooks(ui, repo, other, opts, o)
630 cmdutil.outgoinghooks(ui, repo, other, opts, o)
630 return recurse()
631 return recurse()
631
632
632 if opts.get('newest_first'):
633 if opts.get('newest_first'):
633 o.reverse()
634 o.reverse()
634 displayer = cmdutil.show_changeset(ui, repo, opts)
635 displayer = cmdutil.show_changeset(ui, repo, opts)
635 count = 0
636 count = 0
636 for n in o:
637 for n in o:
637 if limit is not None and count >= limit:
638 if limit is not None and count >= limit:
638 break
639 break
639 parents = [p for p in repo.changelog.parents(n) if p != nullid]
640 parents = [p for p in repo.changelog.parents(n) if p != nullid]
640 if opts.get('no_merges') and len(parents) == 2:
641 if opts.get('no_merges') and len(parents) == 2:
641 continue
642 continue
642 count += 1
643 count += 1
643 displayer.show(repo[n])
644 displayer.show(repo[n])
644 displayer.close()
645 displayer.close()
645 cmdutil.outgoinghooks(ui, repo, other, opts, o)
646 cmdutil.outgoinghooks(ui, repo, other, opts, o)
646 recurse()
647 recurse()
647 return 0 # exit code is zero since we found outgoing changes
648 return 0 # exit code is zero since we found outgoing changes
648
649
649 def revert(repo, node, choose):
650 def revert(repo, node, choose):
650 """revert changes to revision in node without updating dirstate"""
651 """revert changes to revision in node without updating dirstate"""
651 return mergemod.update(repo, node, False, True, choose)[3] > 0
652 return mergemod.update(repo, node, False, True, choose)[3] > 0
652
653
653 def verify(repo):
654 def verify(repo):
654 """verify the consistency of a repository"""
655 """verify the consistency of a repository"""
655 return verifymod.verify(repo)
656 return verifymod.verify(repo)
656
657
657 def remoteui(src, opts):
658 def remoteui(src, opts):
658 'build a remote ui from ui or repo and opts'
659 'build a remote ui from ui or repo and opts'
659 if util.safehasattr(src, 'baseui'): # looks like a repository
660 if util.safehasattr(src, 'baseui'): # looks like a repository
660 dst = src.baseui.copy() # drop repo-specific config
661 dst = src.baseui.copy() # drop repo-specific config
661 src = src.ui # copy target options from repo
662 src = src.ui # copy target options from repo
662 else: # assume it's a global ui object
663 else: # assume it's a global ui object
663 dst = src.copy() # keep all global options
664 dst = src.copy() # keep all global options
664
665
665 # copy ssh-specific options
666 # copy ssh-specific options
666 for o in 'ssh', 'remotecmd':
667 for o in 'ssh', 'remotecmd':
667 v = opts.get(o) or src.config('ui', o)
668 v = opts.get(o) or src.config('ui', o)
668 if v:
669 if v:
669 dst.setconfig("ui", o, v, 'copied')
670 dst.setconfig("ui", o, v, 'copied')
670
671
671 # copy bundle-specific options
672 # copy bundle-specific options
672 r = src.config('bundle', 'mainreporoot')
673 r = src.config('bundle', 'mainreporoot')
673 if r:
674 if r:
674 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
675 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
675
676
676 # copy selected local settings to the remote ui
677 # copy selected local settings to the remote ui
677 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
678 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
678 for key, val in src.configitems(sect):
679 for key, val in src.configitems(sect):
679 dst.setconfig(sect, key, val, 'copied')
680 dst.setconfig(sect, key, val, 'copied')
680 v = src.config('web', 'cacerts')
681 v = src.config('web', 'cacerts')
681 if v:
682 if v:
682 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
683 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
683
684
684 return dst
685 return dst
@@ -1,224 +1,225 b''
1 This test tries to exercise the ssh functionality with a dummy script
1 This test tries to exercise the ssh functionality with a dummy script
2
2
3 $ checknewrepo()
3 $ checknewrepo()
4 > {
4 > {
5 > name=$1
5 > name=$1
6 > if [ -d "$name"/.hg/store ]; then
6 > if [ -d "$name"/.hg/store ]; then
7 > echo store created
7 > echo store created
8 > fi
8 > fi
9 > if [ -f "$name"/.hg/00changelog.i ]; then
9 > if [ -f "$name"/.hg/00changelog.i ]; then
10 > echo 00changelog.i created
10 > echo 00changelog.i created
11 > fi
11 > fi
12 > cat "$name"/.hg/requires
12 > cat "$name"/.hg/requires
13 > }
13 > }
14
14
15 creating 'local'
15 creating 'local'
16
16
17 $ hg init local
17 $ hg init local
18 $ checknewrepo local
18 $ checknewrepo local
19 store created
19 store created
20 00changelog.i created
20 00changelog.i created
21 dotencode
21 dotencode
22 fncache
22 fncache
23 revlogv1
23 revlogv1
24 store
24 store
25 $ echo this > local/foo
25 $ echo this > local/foo
26 $ hg ci --cwd local -A -m "init"
26 $ hg ci --cwd local -A -m "init"
27 adding foo
27 adding foo
28
28
29 test custom revlog chunk cache sizes
29 test custom revlog chunk cache sizes
30
30
31 $ hg --config format.chunkcachesize=0 log -R local -pv
31 $ hg --config format.chunkcachesize=0 log -R local -pv
32 abort: revlog chunk cache size 0 is not greater than 0!
32 abort: revlog chunk cache size 0 is not greater than 0!
33 [255]
33 [255]
34 $ hg --config format.chunkcachesize=1023 log -R local -pv
34 $ hg --config format.chunkcachesize=1023 log -R local -pv
35 abort: revlog chunk cache size 1023 is not a power of 2!
35 abort: revlog chunk cache size 1023 is not a power of 2!
36 [255]
36 [255]
37 $ hg --config format.chunkcachesize=1024 log -R local -pv
37 $ hg --config format.chunkcachesize=1024 log -R local -pv
38 changeset: 0:08b9e9f63b32
38 changeset: 0:08b9e9f63b32
39 tag: tip
39 tag: tip
40 user: test
40 user: test
41 date: Thu Jan 01 00:00:00 1970 +0000
41 date: Thu Jan 01 00:00:00 1970 +0000
42 files: foo
42 files: foo
43 description:
43 description:
44 init
44 init
45
45
46
46
47 diff -r 000000000000 -r 08b9e9f63b32 foo
47 diff -r 000000000000 -r 08b9e9f63b32 foo
48 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
49 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
50 @@ -0,0 +1,1 @@
50 @@ -0,0 +1,1 @@
51 +this
51 +this
52
52
53
53
54 creating repo with format.usestore=false
54 creating repo with format.usestore=false
55
55
56 $ hg --config format.usestore=false init old
56 $ hg --config format.usestore=false init old
57 $ checknewrepo old
57 $ checknewrepo old
58 revlogv1
58 revlogv1
59
59
60 creating repo with format.usefncache=false
60 creating repo with format.usefncache=false
61
61
62 $ hg --config format.usefncache=false init old2
62 $ hg --config format.usefncache=false init old2
63 $ checknewrepo old2
63 $ checknewrepo old2
64 store created
64 store created
65 00changelog.i created
65 00changelog.i created
66 revlogv1
66 revlogv1
67 store
67 store
68
68
69 creating repo with format.dotencode=false
69 creating repo with format.dotencode=false
70
70
71 $ hg --config format.dotencode=false init old3
71 $ hg --config format.dotencode=false init old3
72 $ checknewrepo old3
72 $ checknewrepo old3
73 store created
73 store created
74 00changelog.i created
74 00changelog.i created
75 fncache
75 fncache
76 revlogv1
76 revlogv1
77 store
77 store
78
78
79 test failure
79 test failure
80
80
81 $ hg init local
81 $ hg init local
82 abort: repository local already exists!
82 abort: repository local already exists!
83 [255]
83 [255]
84
84
85 init+push to remote2
85 init+push to remote2
86
86
87 $ hg init -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
87 $ hg init -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
88 $ hg incoming -R remote2 local
88 $ hg incoming -R remote2 local
89 comparing with local
89 comparing with local
90 changeset: 0:08b9e9f63b32
90 changeset: 0:08b9e9f63b32
91 tag: tip
91 tag: tip
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
94 summary: init
94 summary: init
95
95
96
96
97 $ hg push -R local -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
97 $ hg push -R local -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
98 pushing to ssh://user@dummy/remote2
98 pushing to ssh://user@dummy/remote2
99 searching for changes
99 searching for changes
100 remote: adding changesets
100 remote: adding changesets
101 remote: adding manifests
101 remote: adding manifests
102 remote: adding file changes
102 remote: adding file changes
103 remote: added 1 changesets with 1 changes to 1 files
103 remote: added 1 changesets with 1 changes to 1 files
104
104
105 clone to remote1
105 clone to remote1
106
106
107 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
107 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
108 searching for changes
108 searching for changes
109 remote: adding changesets
109 remote: adding changesets
110 remote: adding manifests
110 remote: adding manifests
111 remote: adding file changes
111 remote: adding file changes
112 remote: added 1 changesets with 1 changes to 1 files
112 remote: added 1 changesets with 1 changes to 1 files
113
113
114 init to existing repo
114 init to existing repo
115
115
116 $ hg init -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote1
116 $ hg init -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote1
117 abort: repository remote1 already exists!
117 abort: repository remote1 already exists!
118 abort: could not create remote repo!
118 abort: could not create remote repo!
119 [255]
119 [255]
120
120
121 clone to existing repo
121 clone to existing repo
122
122
123 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
123 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
124 abort: repository remote1 already exists!
124 abort: repository remote1 already exists!
125 abort: could not create remote repo!
125 abort: could not create remote repo!
126 [255]
126 [255]
127
127
128 output of dummyssh
128 output of dummyssh
129
129
130 $ cat dummylog
130 $ cat dummylog
131 Got arguments 1:user@dummy 2:hg init remote2
131 Got arguments 1:user@dummy 2:hg init remote2
132 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
132 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
133 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
133 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
134 Got arguments 1:user@dummy 2:hg init remote1
134 Got arguments 1:user@dummy 2:hg init remote1
135 Got arguments 1:user@dummy 2:hg -R remote1 serve --stdio
135 Got arguments 1:user@dummy 2:hg -R remote1 serve --stdio
136 Got arguments 1:user@dummy 2:hg init remote1
136 Got arguments 1:user@dummy 2:hg init remote1
137 Got arguments 1:user@dummy 2:hg init remote1
137 Got arguments 1:user@dummy 2:hg init remote1
138
138
139 comparing repositories
139 comparing repositories
140
140
141 $ hg tip -q -R local
141 $ hg tip -q -R local
142 0:08b9e9f63b32
142 0:08b9e9f63b32
143 $ hg tip -q -R remote1
143 $ hg tip -q -R remote1
144 0:08b9e9f63b32
144 0:08b9e9f63b32
145 $ hg tip -q -R remote2
145 $ hg tip -q -R remote2
146 0:08b9e9f63b32
146 0:08b9e9f63b32
147
147
148 check names for repositories (clashes with URL schemes, special chars)
148 check names for repositories (clashes with URL schemes, special chars)
149
149
150 $ for i in bundle file hg http https old-http ssh static-http "with space"; do
150 $ for i in bundle file hg http https old-http ssh static-http "with space"; do
151 > printf "hg init \"$i\"... "
151 > printf "hg init \"$i\"... "
152 > hg init "$i"
152 > hg init "$i"
153 > test -d "$i" -a -d "$i/.hg" && echo "ok" || echo "failed"
153 > test -d "$i" -a -d "$i/.hg" && echo "ok" || echo "failed"
154 > done
154 > done
155 hg init "bundle"... ok
155 hg init "bundle"... ok
156 hg init "file"... ok
156 hg init "file"... ok
157 hg init "hg"... ok
157 hg init "hg"... ok
158 hg init "http"... ok
158 hg init "http"... ok
159 hg init "https"... ok
159 hg init "https"... ok
160 hg init "old-http"... ok
160 hg init "old-http"... ok
161 hg init "ssh"... ok
161 hg init "ssh"... ok
162 hg init "static-http"... ok
162 hg init "static-http"... ok
163 hg init "with space"... ok
163 hg init "with space"... ok
164 #if eol-in-paths
164 #if eol-in-paths
165 /* " " is not a valid name for a directory on Windows */
165 /* " " is not a valid name for a directory on Windows */
166 $ hg init " "
166 $ hg init " "
167 $ test -d " "
167 $ test -d " "
168 $ test -d " /.hg"
168 $ test -d " /.hg"
169 #endif
169 #endif
170
170
171 creating 'local/sub/repo'
171 creating 'local/sub/repo'
172
172
173 $ hg init local/sub/repo
173 $ hg init local/sub/repo
174 $ checknewrepo local/sub/repo
174 $ checknewrepo local/sub/repo
175 store created
175 store created
176 00changelog.i created
176 00changelog.i created
177 dotencode
177 dotencode
178 fncache
178 fncache
179 revlogv1
179 revlogv1
180 store
180 store
181
181
182 prepare test of init of url configured from paths
182 prepare test of init of url configured from paths
183
183
184 $ echo '[paths]' >> $HGRCPATH
184 $ echo '[paths]' >> $HGRCPATH
185 $ echo "somewhere = `pwd`/url from paths" >> $HGRCPATH
185 $ echo "somewhere = `pwd`/url from paths" >> $HGRCPATH
186 $ echo "elsewhere = `pwd`/another paths url" >> $HGRCPATH
186 $ echo "elsewhere = `pwd`/another paths url" >> $HGRCPATH
187
187
188 init should (for consistency with clone) expand the url
188 init should (for consistency with clone) expand the url
189
189
190 $ hg init somewhere
190 $ hg init somewhere
191 $ checknewrepo "url from paths"
191 $ checknewrepo "url from paths"
192 store created
192 store created
193 00changelog.i created
193 00changelog.i created
194 dotencode
194 dotencode
195 fncache
195 fncache
196 revlogv1
196 revlogv1
197 store
197 store
198
198
199 verify that clone also expand urls
199 verify that clone also expand urls
200
200
201 $ hg clone somewhere elsewhere
201 $ hg clone somewhere elsewhere
202 updating to branch default
202 updating to branch default
203 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 $ checknewrepo "another paths url"
204 $ checknewrepo "another paths url"
205 store created
205 store created
206 00changelog.i created
206 00changelog.i created
207 dotencode
207 dotencode
208 fncache
208 fncache
209 revlogv1
209 revlogv1
210 store
210 store
211
211
212 clone bookmarks
212 clone bookmarks
213
213
214 $ hg -R local bookmark test
214 $ hg -R local bookmark test
215 $ hg -R local bookmarks
215 $ hg -R local bookmarks
216 * test 0:08b9e9f63b32
216 * test 0:08b9e9f63b32
217 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote-bookmarks
217 $ hg clone -e "python \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote-bookmarks
218 searching for changes
218 searching for changes
219 remote: adding changesets
219 remote: adding changesets
220 remote: adding manifests
220 remote: adding manifests
221 remote: adding file changes
221 remote: adding file changes
222 remote: added 1 changesets with 1 changes to 1 files
222 remote: added 1 changesets with 1 changes to 1 files
223 exporting bookmark test
223 $ hg -R remote-bookmarks bookmarks
224 $ hg -R remote-bookmarks bookmarks
224 test 0:08b9e9f63b32
225 test 0:08b9e9f63b32
General Comments 0
You need to be logged in to leave comments. Login now