##// END OF EJS Templates
clone: update to @ bookmark if it exists
Kevin Bullock -
r17756:92980a8d default
parent child Browse files
Show More
@@ -1,610 +1,610 b''
1 1 # hg.py - repository classes for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from i18n import _
10 10 from lock import release
11 11 from node import hex, nullid
12 12 import localrepo, bundlerepo, httppeer, sshpeer, statichttprepo, bookmarks
13 13 import lock, util, extensions, error, node, scmutil, phases
14 14 import cmdutil, discovery
15 15 import merge as mergemod
16 16 import verify as verifymod
17 17 import errno, os, shutil
18 18
19 19 def _local(path):
20 20 path = util.expandpath(util.urllocalpath(path))
21 21 return (os.path.isfile(path) and bundlerepo or localrepo)
22 22
23 23 def addbranchrevs(lrepo, other, branches, revs):
24 24 peer = other.peer() # a courtesy to callers using a localrepo for other
25 25 hashbranch, branches = branches
26 26 if not hashbranch and not branches:
27 27 return revs or None, revs and revs[0] or None
28 28 revs = revs and list(revs) or []
29 29 if not peer.capable('branchmap'):
30 30 if branches:
31 31 raise util.Abort(_("remote branch lookup not supported"))
32 32 revs.append(hashbranch)
33 33 return revs, revs[0]
34 34 branchmap = peer.branchmap()
35 35
36 36 def primary(branch):
37 37 if branch == '.':
38 38 if not lrepo:
39 39 raise util.Abort(_("dirstate branch not accessible"))
40 40 branch = lrepo.dirstate.branch()
41 41 if branch in branchmap:
42 42 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
43 43 return True
44 44 else:
45 45 return False
46 46
47 47 for branch in branches:
48 48 if not primary(branch):
49 49 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
50 50 if hashbranch:
51 51 if not primary(hashbranch):
52 52 revs.append(hashbranch)
53 53 return revs, revs[0]
54 54
55 55 def parseurl(path, branches=None):
56 56 '''parse url#branch, returning (url, (branch, branches))'''
57 57
58 58 u = util.url(path)
59 59 branch = None
60 60 if u.fragment:
61 61 branch = u.fragment
62 62 u.fragment = None
63 63 return str(u), (branch, branches or [])
64 64
65 65 schemes = {
66 66 'bundle': bundlerepo,
67 67 'file': _local,
68 68 'http': httppeer,
69 69 'https': httppeer,
70 70 'ssh': sshpeer,
71 71 'static-http': statichttprepo,
72 72 }
73 73
74 74 def _peerlookup(path):
75 75 u = util.url(path)
76 76 scheme = u.scheme or 'file'
77 77 thing = schemes.get(scheme) or schemes['file']
78 78 try:
79 79 return thing(path)
80 80 except TypeError:
81 81 return thing
82 82
83 83 def islocal(repo):
84 84 '''return true if repo or path is local'''
85 85 if isinstance(repo, str):
86 86 try:
87 87 return _peerlookup(repo).islocal(repo)
88 88 except AttributeError:
89 89 return False
90 90 return repo.local()
91 91
92 92 def _peerorrepo(ui, path, create=False):
93 93 """return a repository object for the specified path"""
94 94 obj = _peerlookup(path).instance(ui, path, create)
95 95 ui = getattr(obj, "ui", ui)
96 96 for name, module in extensions.extensions():
97 97 hook = getattr(module, 'reposetup', None)
98 98 if hook:
99 99 hook(ui, obj)
100 100 return obj
101 101
102 102 def repository(ui, path='', create=False):
103 103 """return a repository object for the specified path"""
104 104 peer = _peerorrepo(ui, path, create)
105 105 repo = peer.local()
106 106 if not repo:
107 107 raise util.Abort(_("repository '%s' is not local") %
108 108 (path or peer.url()))
109 109 return repo
110 110
111 111 def peer(uiorrepo, opts, path, create=False):
112 112 '''return a repository peer for the specified path'''
113 113 rui = remoteui(uiorrepo, opts)
114 114 return _peerorrepo(rui, path, create).peer()
115 115
116 116 def defaultdest(source):
117 117 '''return default destination of clone if none is given'''
118 118 return os.path.basename(os.path.normpath(source))
119 119
120 120 def share(ui, source, dest=None, update=True):
121 121 '''create a shared repository'''
122 122
123 123 if not islocal(source):
124 124 raise util.Abort(_('can only share local repositories'))
125 125
126 126 if not dest:
127 127 dest = defaultdest(source)
128 128 else:
129 129 dest = ui.expandpath(dest)
130 130
131 131 if isinstance(source, str):
132 132 origsource = ui.expandpath(source)
133 133 source, branches = parseurl(origsource)
134 134 srcrepo = repository(ui, source)
135 135 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
136 136 else:
137 137 srcrepo = source.local()
138 138 origsource = source = srcrepo.url()
139 139 checkout = None
140 140
141 141 sharedpath = srcrepo.sharedpath # if our source is already sharing
142 142
143 143 root = os.path.realpath(dest)
144 144 roothg = os.path.join(root, '.hg')
145 145
146 146 if os.path.exists(roothg):
147 147 raise util.Abort(_('destination already exists'))
148 148
149 149 if not os.path.isdir(root):
150 150 os.mkdir(root)
151 151 util.makedir(roothg, notindexed=True)
152 152
153 153 requirements = ''
154 154 try:
155 155 requirements = srcrepo.opener.read('requires')
156 156 except IOError, inst:
157 157 if inst.errno != errno.ENOENT:
158 158 raise
159 159
160 160 requirements += 'shared\n'
161 161 util.writefile(os.path.join(roothg, 'requires'), requirements)
162 162 util.writefile(os.path.join(roothg, 'sharedpath'), sharedpath)
163 163
164 164 r = repository(ui, root)
165 165
166 166 default = srcrepo.ui.config('paths', 'default')
167 167 if default:
168 168 fp = r.opener("hgrc", "w", text=True)
169 169 fp.write("[paths]\n")
170 170 fp.write("default = %s\n" % default)
171 171 fp.close()
172 172
173 173 if update:
174 174 r.ui.status(_("updating working directory\n"))
175 175 if update is not True:
176 176 checkout = update
177 177 for test in (checkout, 'default', 'tip'):
178 178 if test is None:
179 179 continue
180 180 try:
181 181 uprev = r.lookup(test)
182 182 break
183 183 except error.RepoLookupError:
184 184 continue
185 185 _update(r, uprev)
186 186
187 187 def copystore(ui, srcrepo, destpath):
188 188 '''copy files from store of srcrepo in destpath
189 189
190 190 returns destlock
191 191 '''
192 192 destlock = None
193 193 try:
194 194 hardlink = None
195 195 num = 0
196 196 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
197 197 for f in srcrepo.store.copylist():
198 198 if srcpublishing and f.endswith('phaseroots'):
199 199 continue
200 200 src = os.path.join(srcrepo.sharedpath, f)
201 201 dst = os.path.join(destpath, f)
202 202 dstbase = os.path.dirname(dst)
203 203 if dstbase and not os.path.exists(dstbase):
204 204 os.mkdir(dstbase)
205 205 if os.path.exists(src):
206 206 if dst.endswith('data'):
207 207 # lock to avoid premature writing to the target
208 208 destlock = lock.lock(os.path.join(dstbase, "lock"))
209 209 hardlink, n = util.copyfiles(src, dst, hardlink)
210 210 num += n
211 211 if hardlink:
212 212 ui.debug("linked %d files\n" % num)
213 213 else:
214 214 ui.debug("copied %d files\n" % num)
215 215 return destlock
216 216 except: # re-raises
217 217 release(destlock)
218 218 raise
219 219
220 220 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
221 221 update=True, stream=False, branch=None):
222 222 """Make a copy of an existing repository.
223 223
224 224 Create a copy of an existing repository in a new directory. The
225 225 source and destination are URLs, as passed to the repository
226 226 function. Returns a pair of repository peers, the source and
227 227 newly created destination.
228 228
229 229 The location of the source is added to the new repository's
230 230 .hg/hgrc file, as the default to be used for future pulls and
231 231 pushes.
232 232
233 233 If an exception is raised, the partly cloned/updated destination
234 234 repository will be deleted.
235 235
236 236 Arguments:
237 237
238 238 source: repository object or URL
239 239
240 240 dest: URL of destination repository to create (defaults to base
241 241 name of source repository)
242 242
243 243 pull: always pull from source repository, even in local case
244 244
245 245 stream: stream raw data uncompressed from repository (fast over
246 246 LAN, slow over WAN)
247 247
248 248 rev: revision to clone up to (implies pull=True)
249 249
250 250 update: update working directory after clone completes, if
251 251 destination is local repository (True means update to default rev,
252 252 anything else is treated as a revision)
253 253
254 254 branch: branches to clone
255 255 """
256 256
257 257 if isinstance(source, str):
258 258 origsource = ui.expandpath(source)
259 259 source, branch = parseurl(origsource, branch)
260 260 srcpeer = peer(ui, peeropts, source)
261 261 else:
262 262 srcpeer = source.peer() # in case we were called with a localrepo
263 263 branch = (None, branch or [])
264 264 origsource = source = srcpeer.url()
265 265 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
266 266
267 267 if dest is None:
268 268 dest = defaultdest(source)
269 269 ui.status(_("destination directory: %s\n") % dest)
270 270 else:
271 271 dest = ui.expandpath(dest)
272 272
273 273 dest = util.urllocalpath(dest)
274 274 source = util.urllocalpath(source)
275 275
276 276 if not dest:
277 277 raise util.Abort(_("empty destination path is not valid"))
278 278 if os.path.exists(dest):
279 279 if not os.path.isdir(dest):
280 280 raise util.Abort(_("destination '%s' already exists") % dest)
281 281 elif os.listdir(dest):
282 282 raise util.Abort(_("destination '%s' is not empty") % dest)
283 283
284 284 class DirCleanup(object):
285 285 def __init__(self, dir_):
286 286 self.rmtree = shutil.rmtree
287 287 self.dir_ = dir_
288 288 def close(self):
289 289 self.dir_ = None
290 290 def cleanup(self):
291 291 if self.dir_:
292 292 self.rmtree(self.dir_, True)
293 293
294 294 srclock = destlock = dircleanup = None
295 295 srcrepo = srcpeer.local()
296 296 try:
297 297 abspath = origsource
298 298 if islocal(origsource):
299 299 abspath = os.path.abspath(util.urllocalpath(origsource))
300 300
301 301 if islocal(dest):
302 302 dircleanup = DirCleanup(dest)
303 303
304 304 copy = False
305 305 if (srcrepo and srcrepo.cancopy() and islocal(dest)
306 306 and not phases.hassecret(srcrepo)):
307 307 copy = not pull and not rev
308 308
309 309 if copy:
310 310 try:
311 311 # we use a lock here because if we race with commit, we
312 312 # can end up with extra data in the cloned revlogs that's
313 313 # not pointed to by changesets, thus causing verify to
314 314 # fail
315 315 srclock = srcrepo.lock(wait=False)
316 316 except error.LockError:
317 317 copy = False
318 318
319 319 if copy:
320 320 srcrepo.hook('preoutgoing', throw=True, source='clone')
321 321 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
322 322 if not os.path.exists(dest):
323 323 os.mkdir(dest)
324 324 else:
325 325 # only clean up directories we create ourselves
326 326 dircleanup.dir_ = hgdir
327 327 try:
328 328 destpath = hgdir
329 329 util.makedir(destpath, notindexed=True)
330 330 except OSError, inst:
331 331 if inst.errno == errno.EEXIST:
332 332 dircleanup.close()
333 333 raise util.Abort(_("destination '%s' already exists")
334 334 % dest)
335 335 raise
336 336
337 337 destlock = copystore(ui, srcrepo, destpath)
338 338
339 339 # Recomputing branch cache might be slow on big repos,
340 340 # so just copy it
341 341 dstcachedir = os.path.join(destpath, 'cache')
342 342 srcbranchcache = srcrepo.sjoin('cache/branchheads')
343 343 dstbranchcache = os.path.join(dstcachedir, 'branchheads')
344 344 if os.path.exists(srcbranchcache):
345 345 if not os.path.exists(dstcachedir):
346 346 os.mkdir(dstcachedir)
347 347 util.copyfile(srcbranchcache, dstbranchcache)
348 348
349 349 # we need to re-init the repo after manually copying the data
350 350 # into it
351 351 destpeer = peer(ui, peeropts, dest)
352 352 srcrepo.hook('outgoing', source='clone',
353 353 node=node.hex(node.nullid))
354 354 else:
355 355 try:
356 356 destpeer = peer(ui, peeropts, dest, create=True)
357 357 except OSError, inst:
358 358 if inst.errno == errno.EEXIST:
359 359 dircleanup.close()
360 360 raise util.Abort(_("destination '%s' already exists")
361 361 % dest)
362 362 raise
363 363
364 364 revs = None
365 365 if rev:
366 366 if not srcpeer.capable('lookup'):
367 367 raise util.Abort(_("src repository does not support "
368 368 "revision lookup and so doesn't "
369 369 "support clone by revision"))
370 370 revs = [srcpeer.lookup(r) for r in rev]
371 371 checkout = revs[0]
372 372 if destpeer.local():
373 373 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
374 374 elif srcrepo:
375 375 srcrepo.push(destpeer, revs=revs)
376 376 else:
377 377 raise util.Abort(_("clone from remote to remote not supported"))
378 378
379 379 if dircleanup:
380 380 dircleanup.close()
381 381
382 382 # clone all bookmarks except divergent ones
383 383 destrepo = destpeer.local()
384 384 if destrepo and srcpeer.capable("pushkey"):
385 385 rb = srcpeer.listkeys('bookmarks')
386 386 for k, n in rb.iteritems():
387 387 try:
388 388 m = destrepo.lookup(n)
389 389 destrepo._bookmarks[k] = m
390 390 except error.RepoLookupError:
391 391 pass
392 392 if rb:
393 393 bookmarks.write(destrepo)
394 394 elif srcrepo and destpeer.capable("pushkey"):
395 395 for k, n in srcrepo._bookmarks.iteritems():
396 396 destpeer.pushkey('bookmarks', k, '', hex(n))
397 397
398 398 if destrepo:
399 399 fp = destrepo.opener("hgrc", "w", text=True)
400 400 fp.write("[paths]\n")
401 401 u = util.url(abspath)
402 402 u.passwd = None
403 403 defaulturl = str(u)
404 404 fp.write("default = %s\n" % defaulturl)
405 405 fp.close()
406 406
407 407 destrepo.ui.setconfig('paths', 'default', defaulturl)
408 408
409 409 if update:
410 410 if update is not True:
411 411 checkout = srcpeer.lookup(update)
412 for test in (checkout, 'default', 'tip'):
412 for test in (checkout, '@', 'default', 'tip'):
413 413 if test is None:
414 414 continue
415 415 try:
416 416 uprev = destrepo.lookup(test)
417 417 break
418 418 except error.RepoLookupError:
419 419 continue
420 420 bn = destrepo[uprev].branch()
421 421 destrepo.ui.status(_("updating to branch %s\n") % bn)
422 422 _update(destrepo, uprev)
423 423 if update in destrepo._bookmarks:
424 424 bookmarks.setcurrent(destrepo, update)
425 425
426 426 return srcpeer, destpeer
427 427 finally:
428 428 release(srclock, destlock)
429 429 if dircleanup is not None:
430 430 dircleanup.cleanup()
431 431 if srcpeer is not None:
432 432 srcpeer.close()
433 433
434 434 def _showstats(repo, stats):
435 435 repo.ui.status(_("%d files updated, %d files merged, "
436 436 "%d files removed, %d files unresolved\n") % stats)
437 437
438 438 def update(repo, node):
439 439 """update the working directory to node, merging linear changes"""
440 440 stats = mergemod.update(repo, node, False, False, None)
441 441 _showstats(repo, stats)
442 442 if stats[3]:
443 443 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
444 444 return stats[3] > 0
445 445
446 446 # naming conflict in clone()
447 447 _update = update
448 448
449 449 def clean(repo, node, show_stats=True):
450 450 """forcibly switch the working directory to node, clobbering changes"""
451 451 stats = mergemod.update(repo, node, False, True, None)
452 452 if show_stats:
453 453 _showstats(repo, stats)
454 454 return stats[3] > 0
455 455
456 456 def merge(repo, node, force=None, remind=True):
457 457 """Branch merge with node, resolving changes. Return true if any
458 458 unresolved conflicts."""
459 459 stats = mergemod.update(repo, node, True, force, False)
460 460 _showstats(repo, stats)
461 461 if stats[3]:
462 462 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
463 463 "or 'hg update -C .' to abandon\n"))
464 464 elif remind:
465 465 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
466 466 return stats[3] > 0
467 467
468 468 def _incoming(displaychlist, subreporecurse, ui, repo, source,
469 469 opts, buffered=False):
470 470 """
471 471 Helper for incoming / gincoming.
472 472 displaychlist gets called with
473 473 (remoterepo, incomingchangesetlist, displayer) parameters,
474 474 and is supposed to contain only code that can't be unified.
475 475 """
476 476 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
477 477 other = peer(repo, opts, source)
478 478 ui.status(_('comparing with %s\n') % util.hidepassword(source))
479 479 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
480 480
481 481 if revs:
482 482 revs = [other.lookup(rev) for rev in revs]
483 483 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
484 484 revs, opts["bundle"], opts["force"])
485 485 try:
486 486 if not chlist:
487 487 ui.status(_("no changes found\n"))
488 488 return subreporecurse()
489 489
490 490 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
491 491
492 492 # XXX once graphlog extension makes it into core,
493 493 # should be replaced by a if graph/else
494 494 displaychlist(other, chlist, displayer)
495 495
496 496 displayer.close()
497 497 finally:
498 498 cleanupfn()
499 499 subreporecurse()
500 500 return 0 # exit code is zero since we found incoming changes
501 501
502 502 def incoming(ui, repo, source, opts):
503 503 def subreporecurse():
504 504 ret = 1
505 505 if opts.get('subrepos'):
506 506 ctx = repo[None]
507 507 for subpath in sorted(ctx.substate):
508 508 sub = ctx.sub(subpath)
509 509 ret = min(ret, sub.incoming(ui, source, opts))
510 510 return ret
511 511
512 512 def display(other, chlist, displayer):
513 513 limit = cmdutil.loglimit(opts)
514 514 if opts.get('newest_first'):
515 515 chlist.reverse()
516 516 count = 0
517 517 for n in chlist:
518 518 if limit is not None and count >= limit:
519 519 break
520 520 parents = [p for p in other.changelog.parents(n) if p != nullid]
521 521 if opts.get('no_merges') and len(parents) == 2:
522 522 continue
523 523 count += 1
524 524 displayer.show(other[n])
525 525 return _incoming(display, subreporecurse, ui, repo, source, opts)
526 526
527 527 def _outgoing(ui, repo, dest, opts):
528 528 dest = ui.expandpath(dest or 'default-push', dest or 'default')
529 529 dest, branches = parseurl(dest, opts.get('branch'))
530 530 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
531 531 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
532 532 if revs:
533 533 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
534 534
535 535 other = peer(repo, opts, dest)
536 536 outgoing = discovery.findcommonoutgoing(repo, other, revs,
537 537 force=opts.get('force'))
538 538 o = outgoing.missing
539 539 if not o:
540 540 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
541 541 return None
542 542 return o
543 543
544 544 def outgoing(ui, repo, dest, opts):
545 545 def recurse():
546 546 ret = 1
547 547 if opts.get('subrepos'):
548 548 ctx = repo[None]
549 549 for subpath in sorted(ctx.substate):
550 550 sub = ctx.sub(subpath)
551 551 ret = min(ret, sub.outgoing(ui, dest, opts))
552 552 return ret
553 553
554 554 limit = cmdutil.loglimit(opts)
555 555 o = _outgoing(ui, repo, dest, opts)
556 556 if o is None:
557 557 return recurse()
558 558
559 559 if opts.get('newest_first'):
560 560 o.reverse()
561 561 displayer = cmdutil.show_changeset(ui, repo, opts)
562 562 count = 0
563 563 for n in o:
564 564 if limit is not None and count >= limit:
565 565 break
566 566 parents = [p for p in repo.changelog.parents(n) if p != nullid]
567 567 if opts.get('no_merges') and len(parents) == 2:
568 568 continue
569 569 count += 1
570 570 displayer.show(repo[n])
571 571 displayer.close()
572 572 recurse()
573 573 return 0 # exit code is zero since we found outgoing changes
574 574
575 575 def revert(repo, node, choose):
576 576 """revert changes to revision in node without updating dirstate"""
577 577 return mergemod.update(repo, node, False, True, choose)[3] > 0
578 578
579 579 def verify(repo):
580 580 """verify the consistency of a repository"""
581 581 return verifymod.verify(repo)
582 582
583 583 def remoteui(src, opts):
584 584 'build a remote ui from ui or repo and opts'
585 585 if util.safehasattr(src, 'baseui'): # looks like a repository
586 586 dst = src.baseui.copy() # drop repo-specific config
587 587 src = src.ui # copy target options from repo
588 588 else: # assume it's a global ui object
589 589 dst = src.copy() # keep all global options
590 590
591 591 # copy ssh-specific options
592 592 for o in 'ssh', 'remotecmd':
593 593 v = opts.get(o) or src.config('ui', o)
594 594 if v:
595 595 dst.setconfig("ui", o, v)
596 596
597 597 # copy bundle-specific options
598 598 r = src.config('bundle', 'mainreporoot')
599 599 if r:
600 600 dst.setconfig('bundle', 'mainreporoot', r)
601 601
602 602 # copy selected local settings to the remote ui
603 603 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
604 604 for key, val in src.configitems(sect):
605 605 dst.setconfig(sect, key, val)
606 606 v = src.config('web', 'cacerts')
607 607 if v:
608 608 dst.setconfig('web', 'cacerts', util.expandpath(v))
609 609
610 610 return dst
@@ -1,567 +1,577 b''
1 1 Prepare repo a:
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ echo a > a
6 6 $ hg add a
7 7 $ hg commit -m test
8 8 $ echo first line > b
9 9 $ hg add b
10 10
11 11 Create a non-inlined filelog:
12 12
13 13 $ python -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
14 14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 15 > cat data1 >> b
16 16 > hg commit -m test
17 17 > done
18 18
19 19 List files in store/data (should show a 'b.d'):
20 20
21 21 $ for i in .hg/store/data/*; do
22 22 > echo $i
23 23 > done
24 24 .hg/store/data/a.i
25 25 .hg/store/data/b.d
26 26 .hg/store/data/b.i
27 27
28 28 Default operation:
29 29
30 30 $ hg clone . ../b
31 31 updating to branch default
32 32 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 33 $ cd ../b
34 34 $ cat a
35 35 a
36 36 $ hg verify
37 37 checking changesets
38 38 checking manifests
39 39 crosschecking files in changesets and manifests
40 40 checking files
41 41 2 files, 11 changesets, 11 total revisions
42 42
43 43 Invalid dest '' must abort:
44 44
45 45 $ hg clone . ''
46 46 abort: empty destination path is not valid
47 47 [255]
48 48
49 49 No update, with debug option:
50 50
51 51 #if hardlink
52 52 $ hg --debug clone -U . ../c
53 53 linked 8 files
54 54 listing keys for "bookmarks"
55 55 #else
56 56 $ hg --debug clone -U . ../c
57 57 copied 8 files
58 58 listing keys for "bookmarks"
59 59 #endif
60 60 $ cd ../c
61 61 $ cat a 2>/dev/null || echo "a not present"
62 62 a not present
63 63 $ hg verify
64 64 checking changesets
65 65 checking manifests
66 66 crosschecking files in changesets and manifests
67 67 checking files
68 68 2 files, 11 changesets, 11 total revisions
69 69
70 70 Default destination:
71 71
72 72 $ mkdir ../d
73 73 $ cd ../d
74 74 $ hg clone ../a
75 75 destination directory: a
76 76 updating to branch default
77 77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 78 $ cd a
79 79 $ hg cat a
80 80 a
81 81 $ cd ../..
82 82
83 83 Check that we drop the 'file:' from the path before writing the .hgrc:
84 84
85 85 $ hg clone file:a e
86 86 updating to branch default
87 87 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 88 $ grep 'file:' e/.hg/hgrc
89 89 [1]
90 90
91 91 Check that path aliases are expanded:
92 92
93 93 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
94 94 $ hg -R f showconfig paths.default
95 95 $TESTTMP/a#0 (glob)
96 96
97 97 Use --pull:
98 98
99 99 $ hg clone --pull a g
100 100 requesting all changes
101 101 adding changesets
102 102 adding manifests
103 103 adding file changes
104 104 added 11 changesets with 11 changes to 2 files
105 105 updating to branch default
106 106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 107 $ hg -R g verify
108 108 checking changesets
109 109 checking manifests
110 110 crosschecking files in changesets and manifests
111 111 checking files
112 112 2 files, 11 changesets, 11 total revisions
113 113
114 114 Invalid dest '' with --pull must abort (issue2528):
115 115
116 116 $ hg clone --pull a ''
117 117 abort: empty destination path is not valid
118 118 [255]
119 119
120 120 Clone to '.':
121 121
122 122 $ mkdir h
123 123 $ cd h
124 124 $ hg clone ../a .
125 125 updating to branch default
126 126 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 127 $ cd ..
128 128
129 129
130 130 *** Tests for option -u ***
131 131
132 132 Adding some more history to repo a:
133 133
134 134 $ cd a
135 135 $ hg tag ref1
136 136 $ echo the quick brown fox >a
137 137 $ hg ci -m "hacked default"
138 138 $ hg up ref1
139 139 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
140 140 $ hg branch stable
141 141 marked working directory as branch stable
142 142 (branches are permanent and global, did you want a bookmark?)
143 143 $ echo some text >a
144 144 $ hg ci -m "starting branch stable"
145 145 $ hg tag ref2
146 146 $ echo some more text >a
147 147 $ hg ci -m "another change for branch stable"
148 148 $ hg up ref2
149 149 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
150 150 $ hg parents
151 151 changeset: 13:e8ece76546a6
152 152 branch: stable
153 153 tag: ref2
154 154 parent: 10:a7949464abda
155 155 user: test
156 156 date: Thu Jan 01 00:00:00 1970 +0000
157 157 summary: starting branch stable
158 158
159 159
160 160 Repo a has two heads:
161 161
162 162 $ hg heads
163 163 changeset: 15:0aae7cf88f0d
164 164 branch: stable
165 165 tag: tip
166 166 user: test
167 167 date: Thu Jan 01 00:00:00 1970 +0000
168 168 summary: another change for branch stable
169 169
170 170 changeset: 12:f21241060d6a
171 171 user: test
172 172 date: Thu Jan 01 00:00:00 1970 +0000
173 173 summary: hacked default
174 174
175 175
176 176 $ cd ..
177 177
178 178
179 179 Testing --noupdate with --updaterev (must abort):
180 180
181 181 $ hg clone --noupdate --updaterev 1 a ua
182 182 abort: cannot specify both --noupdate and --updaterev
183 183 [255]
184 184
185 185
186 186 Testing clone -u:
187 187
188 188 $ hg clone -u . a ua
189 189 updating to branch stable
190 190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 191
192 192 Repo ua has both heads:
193 193
194 194 $ hg -R ua heads
195 195 changeset: 15:0aae7cf88f0d
196 196 branch: stable
197 197 tag: tip
198 198 user: test
199 199 date: Thu Jan 01 00:00:00 1970 +0000
200 200 summary: another change for branch stable
201 201
202 202 changeset: 12:f21241060d6a
203 203 user: test
204 204 date: Thu Jan 01 00:00:00 1970 +0000
205 205 summary: hacked default
206 206
207 207
208 208 Same revision checked out in repo a and ua:
209 209
210 210 $ hg -R a parents --template "{node|short}\n"
211 211 e8ece76546a6
212 212 $ hg -R ua parents --template "{node|short}\n"
213 213 e8ece76546a6
214 214
215 215 $ rm -r ua
216 216
217 217
218 218 Testing clone --pull -u:
219 219
220 220 $ hg clone --pull -u . a ua
221 221 requesting all changes
222 222 adding changesets
223 223 adding manifests
224 224 adding file changes
225 225 added 16 changesets with 16 changes to 3 files (+1 heads)
226 226 updating to branch stable
227 227 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 228
229 229 Repo ua has both heads:
230 230
231 231 $ hg -R ua heads
232 232 changeset: 15:0aae7cf88f0d
233 233 branch: stable
234 234 tag: tip
235 235 user: test
236 236 date: Thu Jan 01 00:00:00 1970 +0000
237 237 summary: another change for branch stable
238 238
239 239 changeset: 12:f21241060d6a
240 240 user: test
241 241 date: Thu Jan 01 00:00:00 1970 +0000
242 242 summary: hacked default
243 243
244 244
245 245 Same revision checked out in repo a and ua:
246 246
247 247 $ hg -R a parents --template "{node|short}\n"
248 248 e8ece76546a6
249 249 $ hg -R ua parents --template "{node|short}\n"
250 250 e8ece76546a6
251 251
252 252 $ rm -r ua
253 253
254 254
255 255 Testing clone -u <branch>:
256 256
257 257 $ hg clone -u stable a ua
258 258 updating to branch stable
259 259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 260
261 261 Repo ua has both heads:
262 262
263 263 $ hg -R ua heads
264 264 changeset: 15:0aae7cf88f0d
265 265 branch: stable
266 266 tag: tip
267 267 user: test
268 268 date: Thu Jan 01 00:00:00 1970 +0000
269 269 summary: another change for branch stable
270 270
271 271 changeset: 12:f21241060d6a
272 272 user: test
273 273 date: Thu Jan 01 00:00:00 1970 +0000
274 274 summary: hacked default
275 275
276 276
277 277 Branch 'stable' is checked out:
278 278
279 279 $ hg -R ua parents
280 280 changeset: 15:0aae7cf88f0d
281 281 branch: stable
282 282 tag: tip
283 283 user: test
284 284 date: Thu Jan 01 00:00:00 1970 +0000
285 285 summary: another change for branch stable
286 286
287 287
288 288 $ rm -r ua
289 289
290 290
291 291 Testing default checkout:
292 292
293 293 $ hg clone a ua
294 294 updating to branch default
295 295 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 296
297 297 Repo ua has both heads:
298 298
299 299 $ hg -R ua heads
300 300 changeset: 15:0aae7cf88f0d
301 301 branch: stable
302 302 tag: tip
303 303 user: test
304 304 date: Thu Jan 01 00:00:00 1970 +0000
305 305 summary: another change for branch stable
306 306
307 307 changeset: 12:f21241060d6a
308 308 user: test
309 309 date: Thu Jan 01 00:00:00 1970 +0000
310 310 summary: hacked default
311 311
312 312
313 313 Branch 'default' is checked out:
314 314
315 315 $ hg -R ua parents
316 316 changeset: 12:f21241060d6a
317 317 user: test
318 318 date: Thu Jan 01 00:00:00 1970 +0000
319 319 summary: hacked default
320 320
321 321
322 322 $ rm -r ua
323 323
324 324
325 325 Testing #<branch>:
326 326
327 327 $ hg clone -u . a#stable ua
328 328 adding changesets
329 329 adding manifests
330 330 adding file changes
331 331 added 14 changesets with 14 changes to 3 files
332 332 updating to branch stable
333 333 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 334
335 335 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
336 336
337 337 $ hg -R ua heads
338 338 changeset: 13:0aae7cf88f0d
339 339 branch: stable
340 340 tag: tip
341 341 user: test
342 342 date: Thu Jan 01 00:00:00 1970 +0000
343 343 summary: another change for branch stable
344 344
345 345 changeset: 10:a7949464abda
346 346 user: test
347 347 date: Thu Jan 01 00:00:00 1970 +0000
348 348 summary: test
349 349
350 350
351 351 Same revision checked out in repo a and ua:
352 352
353 353 $ hg -R a parents --template "{node|short}\n"
354 354 e8ece76546a6
355 355 $ hg -R ua parents --template "{node|short}\n"
356 356 e8ece76546a6
357 357
358 358 $ rm -r ua
359 359
360 360
361 361 Testing -u -r <branch>:
362 362
363 363 $ hg clone -u . -r stable a ua
364 364 adding changesets
365 365 adding manifests
366 366 adding file changes
367 367 added 14 changesets with 14 changes to 3 files
368 368 updating to branch stable
369 369 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 370
371 371 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
372 372
373 373 $ hg -R ua heads
374 374 changeset: 13:0aae7cf88f0d
375 375 branch: stable
376 376 tag: tip
377 377 user: test
378 378 date: Thu Jan 01 00:00:00 1970 +0000
379 379 summary: another change for branch stable
380 380
381 381 changeset: 10:a7949464abda
382 382 user: test
383 383 date: Thu Jan 01 00:00:00 1970 +0000
384 384 summary: test
385 385
386 386
387 387 Same revision checked out in repo a and ua:
388 388
389 389 $ hg -R a parents --template "{node|short}\n"
390 390 e8ece76546a6
391 391 $ hg -R ua parents --template "{node|short}\n"
392 392 e8ece76546a6
393 393
394 394 $ rm -r ua
395 395
396 396
397 397 Testing -r <branch>:
398 398
399 399 $ hg clone -r stable a ua
400 400 adding changesets
401 401 adding manifests
402 402 adding file changes
403 403 added 14 changesets with 14 changes to 3 files
404 404 updating to branch stable
405 405 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
406 406
407 407 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
408 408
409 409 $ hg -R ua heads
410 410 changeset: 13:0aae7cf88f0d
411 411 branch: stable
412 412 tag: tip
413 413 user: test
414 414 date: Thu Jan 01 00:00:00 1970 +0000
415 415 summary: another change for branch stable
416 416
417 417 changeset: 10:a7949464abda
418 418 user: test
419 419 date: Thu Jan 01 00:00:00 1970 +0000
420 420 summary: test
421 421
422 422
423 423 Branch 'stable' is checked out:
424 424
425 425 $ hg -R ua parents
426 426 changeset: 13:0aae7cf88f0d
427 427 branch: stable
428 428 tag: tip
429 429 user: test
430 430 date: Thu Jan 01 00:00:00 1970 +0000
431 431 summary: another change for branch stable
432 432
433 433
434 434 $ rm -r ua
435 435
436 436
437 437 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
438 438 iterable in addbranchrevs()
439 439
440 440 $ cat <<EOF > simpleclone.py
441 441 > from mercurial import ui, hg
442 442 > myui = ui.ui()
443 443 > repo = hg.repository(myui, 'a')
444 444 > hg.clone(myui, {}, repo, dest="ua")
445 445 > EOF
446 446
447 447 $ python simpleclone.py
448 448 updating to branch default
449 449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450
451 451 $ rm -r ua
452 452
453 453 $ cat <<EOF > branchclone.py
454 454 > from mercurial import ui, hg, extensions
455 455 > myui = ui.ui()
456 456 > extensions.loadall(myui)
457 457 > repo = hg.repository(myui, 'a')
458 458 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
459 459 > EOF
460 460
461 461 $ python branchclone.py
462 462 adding changesets
463 463 adding manifests
464 464 adding file changes
465 465 added 14 changesets with 14 changes to 3 files
466 466 updating to branch stable
467 467 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
468 468 $ rm -r ua
469 469
470 470
471 Test clone with special '@' bookmark:
472 $ cd a
473 $ hg bookmark -r a7949464abda @ # branch point of stable from default
474 $ hg clone . ../i
475 updating to branch default
476 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
477 $ hg id -i ../i
478 a7949464abda
479
480
471 481 Testing failures:
472 482
473 483 $ mkdir fail
474 484 $ cd fail
475 485
476 486 No local source
477 487
478 488 $ hg clone a b
479 489 abort: repository a not found!
480 490 [255]
481 491
482 492 No remote source
483 493
484 494 $ hg clone http://127.0.0.1:3121/a b
485 495 abort: error: *refused* (glob)
486 496 [255]
487 497 $ rm -rf b # work around bug with http clone
488 498
489 499
490 500 #if unix-permissions
491 501
492 502 Inaccessible source
493 503
494 504 $ mkdir a
495 505 $ chmod 000 a
496 506 $ hg clone a b
497 507 abort: repository a not found!
498 508 [255]
499 509
500 510 Inaccessible destination
501 511
502 512 $ hg init b
503 513 $ cd b
504 514 $ hg clone . ../a
505 515 abort: Permission denied: ../a
506 516 [255]
507 517 $ cd ..
508 518 $ chmod 700 a
509 519 $ rm -r a b
510 520
511 521 #endif
512 522
513 523
514 524 #if fifo
515 525
516 526 Source of wrong type
517 527
518 528 $ mkfifo a
519 529 $ hg clone a b
520 530 abort: repository a not found!
521 531 [255]
522 532 $ rm a
523 533
524 534 #endif
525 535
526 536 Default destination, same directory
527 537
528 538 $ hg init q
529 539 $ hg clone q
530 540 destination directory: q
531 541 abort: destination 'q' is not empty
532 542 [255]
533 543
534 544 destination directory not empty
535 545
536 546 $ mkdir a
537 547 $ echo stuff > a/a
538 548 $ hg clone q a
539 549 abort: destination 'a' is not empty
540 550 [255]
541 551
542 552
543 553 #if unix-permissions
544 554
545 555 leave existing directory in place after clone failure
546 556
547 557 $ hg init c
548 558 $ cd c
549 559 $ echo c > c
550 560 $ hg commit -A -m test
551 561 adding c
552 562 $ chmod -rx .hg/store/data
553 563 $ cd ..
554 564 $ mkdir d
555 565 $ hg clone c d 2> err
556 566 [255]
557 567 $ test -d d
558 568 $ test -d d/.hg
559 569 [1]
560 570
561 571 re-enable perm to allow deletion
562 572
563 573 $ chmod +rx c/.hg/store/data
564 574
565 575 #endif
566 576
567 577 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now