##// END OF EJS Templates
clone: add progress support to hardlink clones (issue3059)
Augie Fackler -
r24440:27ad6b91 default
parent child Browse files
Show More
@@ -1,684 +1,694 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 nullid
12 12
13 13 import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo
14 14 import bookmarks, lock, util, extensions, error, node, scmutil, phases, url
15 15 import cmdutil, discovery, repoview, exchange
16 16 import ui as uimod
17 17 import merge as mergemod
18 18 import verify as verifymod
19 19 import errno, os, shutil
20 20
21 21 def _local(path):
22 22 path = util.expandpath(util.urllocalpath(path))
23 23 return (os.path.isfile(path) and bundlerepo or localrepo)
24 24
25 25 def addbranchrevs(lrepo, other, branches, revs):
26 26 peer = other.peer() # a courtesy to callers using a localrepo for other
27 27 hashbranch, branches = branches
28 28 if not hashbranch and not branches:
29 29 x = revs or None
30 30 if util.safehasattr(revs, 'first'):
31 31 y = revs.first()
32 32 elif revs:
33 33 y = revs[0]
34 34 else:
35 35 y = None
36 36 return x, y
37 37 if revs:
38 38 revs = list(revs)
39 39 else:
40 40 revs = []
41 41
42 42 if not peer.capable('branchmap'):
43 43 if branches:
44 44 raise util.Abort(_("remote branch lookup not supported"))
45 45 revs.append(hashbranch)
46 46 return revs, revs[0]
47 47 branchmap = peer.branchmap()
48 48
49 49 def primary(branch):
50 50 if branch == '.':
51 51 if not lrepo:
52 52 raise util.Abort(_("dirstate branch not accessible"))
53 53 branch = lrepo.dirstate.branch()
54 54 if branch in branchmap:
55 55 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
56 56 return True
57 57 else:
58 58 return False
59 59
60 60 for branch in branches:
61 61 if not primary(branch):
62 62 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
63 63 if hashbranch:
64 64 if not primary(hashbranch):
65 65 revs.append(hashbranch)
66 66 return revs, revs[0]
67 67
68 68 def parseurl(path, branches=None):
69 69 '''parse url#branch, returning (url, (branch, branches))'''
70 70
71 71 u = util.url(path)
72 72 branch = None
73 73 if u.fragment:
74 74 branch = u.fragment
75 75 u.fragment = None
76 76 return str(u), (branch, branches or [])
77 77
78 78 schemes = {
79 79 'bundle': bundlerepo,
80 80 'union': unionrepo,
81 81 'file': _local,
82 82 'http': httppeer,
83 83 'https': httppeer,
84 84 'ssh': sshpeer,
85 85 'static-http': statichttprepo,
86 86 }
87 87
88 88 def _peerlookup(path):
89 89 u = util.url(path)
90 90 scheme = u.scheme or 'file'
91 91 thing = schemes.get(scheme) or schemes['file']
92 92 try:
93 93 return thing(path)
94 94 except TypeError:
95 95 return thing
96 96
97 97 def islocal(repo):
98 98 '''return true if repo (or path pointing to repo) is local'''
99 99 if isinstance(repo, str):
100 100 try:
101 101 return _peerlookup(repo).islocal(repo)
102 102 except AttributeError:
103 103 return False
104 104 return repo.local()
105 105
106 106 def openpath(ui, path):
107 107 '''open path with open if local, url.open if remote'''
108 108 pathurl = util.url(path, parsequery=False, parsefragment=False)
109 109 if pathurl.islocal():
110 110 return util.posixfile(pathurl.localpath(), 'rb')
111 111 else:
112 112 return url.open(ui, path)
113 113
114 114 # a list of (ui, repo) functions called for wire peer initialization
115 115 wirepeersetupfuncs = []
116 116
117 117 def _peerorrepo(ui, path, create=False):
118 118 """return a repository object for the specified path"""
119 119 obj = _peerlookup(path).instance(ui, path, create)
120 120 ui = getattr(obj, "ui", ui)
121 121 for name, module in extensions.extensions(ui):
122 122 hook = getattr(module, 'reposetup', None)
123 123 if hook:
124 124 hook(ui, obj)
125 125 if not obj.local():
126 126 for f in wirepeersetupfuncs:
127 127 f(ui, obj)
128 128 return obj
129 129
130 130 def repository(ui, path='', create=False):
131 131 """return a repository object for the specified path"""
132 132 peer = _peerorrepo(ui, path, create)
133 133 repo = peer.local()
134 134 if not repo:
135 135 raise util.Abort(_("repository '%s' is not local") %
136 136 (path or peer.url()))
137 137 return repo.filtered('visible')
138 138
139 139 def peer(uiorrepo, opts, path, create=False):
140 140 '''return a repository peer for the specified path'''
141 141 rui = remoteui(uiorrepo, opts)
142 142 return _peerorrepo(rui, path, create).peer()
143 143
144 144 def defaultdest(source):
145 145 '''return default destination of clone if none is given
146 146
147 147 >>> defaultdest('foo')
148 148 'foo'
149 149 >>> defaultdest('/foo/bar')
150 150 'bar'
151 151 >>> defaultdest('/')
152 152 ''
153 153 >>> defaultdest('')
154 154 ''
155 155 >>> defaultdest('http://example.org/')
156 156 ''
157 157 >>> defaultdest('http://example.org/foo/')
158 158 'foo'
159 159 '''
160 160 path = util.url(source).path
161 161 if not path:
162 162 return ''
163 163 return os.path.basename(os.path.normpath(path))
164 164
165 165 def share(ui, source, dest=None, update=True, bookmarks=True):
166 166 '''create a shared repository'''
167 167
168 168 if not islocal(source):
169 169 raise util.Abort(_('can only share local repositories'))
170 170
171 171 if not dest:
172 172 dest = defaultdest(source)
173 173 else:
174 174 dest = ui.expandpath(dest)
175 175
176 176 if isinstance(source, str):
177 177 origsource = ui.expandpath(source)
178 178 source, branches = parseurl(origsource)
179 179 srcrepo = repository(ui, source)
180 180 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
181 181 else:
182 182 srcrepo = source.local()
183 183 origsource = source = srcrepo.url()
184 184 checkout = None
185 185
186 186 sharedpath = srcrepo.sharedpath # if our source is already sharing
187 187
188 188 destwvfs = scmutil.vfs(dest, realpath=True)
189 189 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
190 190
191 191 if destvfs.lexists():
192 192 raise util.Abort(_('destination already exists'))
193 193
194 194 if not destwvfs.isdir():
195 195 destwvfs.mkdir()
196 196 destvfs.makedir()
197 197
198 198 requirements = ''
199 199 try:
200 200 requirements = srcrepo.vfs.read('requires')
201 201 except IOError, inst:
202 202 if inst.errno != errno.ENOENT:
203 203 raise
204 204
205 205 requirements += 'shared\n'
206 206 destvfs.write('requires', requirements)
207 207 destvfs.write('sharedpath', sharedpath)
208 208
209 209 r = repository(ui, destwvfs.base)
210 210
211 211 default = srcrepo.ui.config('paths', 'default')
212 212 if default:
213 213 fp = r.vfs("hgrc", "w", text=True)
214 214 fp.write("[paths]\n")
215 215 fp.write("default = %s\n" % default)
216 216 fp.close()
217 217
218 218 if update:
219 219 r.ui.status(_("updating working directory\n"))
220 220 if update is not True:
221 221 checkout = update
222 222 for test in (checkout, 'default', 'tip'):
223 223 if test is None:
224 224 continue
225 225 try:
226 226 uprev = r.lookup(test)
227 227 break
228 228 except error.RepoLookupError:
229 229 continue
230 230 _update(r, uprev)
231 231
232 232 if bookmarks:
233 233 fp = r.vfs('shared', 'w')
234 234 fp.write('bookmarks\n')
235 235 fp.close()
236 236
237 237 def copystore(ui, srcrepo, destpath):
238 238 '''copy files from store of srcrepo in destpath
239 239
240 240 returns destlock
241 241 '''
242 242 destlock = None
243 243 try:
244 244 hardlink = None
245 245 num = 0
246 closetopic = [None]
247 def prog(topic, pos):
248 if pos is None:
249 closetopic[0] = topic
250 else:
251 ui.progress(topic, pos + num)
246 252 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
247 253 srcvfs = scmutil.vfs(srcrepo.sharedpath)
248 254 dstvfs = scmutil.vfs(destpath)
249 255 for f in srcrepo.store.copylist():
250 256 if srcpublishing and f.endswith('phaseroots'):
251 257 continue
252 258 dstbase = os.path.dirname(f)
253 259 if dstbase and not dstvfs.exists(dstbase):
254 260 dstvfs.mkdir(dstbase)
255 261 if srcvfs.exists(f):
256 262 if f.endswith('data'):
257 263 # 'dstbase' may be empty (e.g. revlog format 0)
258 264 lockfile = os.path.join(dstbase, "lock")
259 265 # lock to avoid premature writing to the target
260 266 destlock = lock.lock(dstvfs, lockfile)
261 267 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
262 hardlink)
268 hardlink, progress=prog)
263 269 num += n
264 270 if hardlink:
265 271 ui.debug("linked %d files\n" % num)
272 if closetopic[0]:
273 ui.progress(closetopic[0], None)
266 274 else:
267 275 ui.debug("copied %d files\n" % num)
276 if closetopic[0]:
277 ui.progress(closetopic[0], None)
268 278 return destlock
269 279 except: # re-raises
270 280 release(destlock)
271 281 raise
272 282
273 283 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
274 284 update=True, stream=False, branch=None):
275 285 """Make a copy of an existing repository.
276 286
277 287 Create a copy of an existing repository in a new directory. The
278 288 source and destination are URLs, as passed to the repository
279 289 function. Returns a pair of repository peers, the source and
280 290 newly created destination.
281 291
282 292 The location of the source is added to the new repository's
283 293 .hg/hgrc file, as the default to be used for future pulls and
284 294 pushes.
285 295
286 296 If an exception is raised, the partly cloned/updated destination
287 297 repository will be deleted.
288 298
289 299 Arguments:
290 300
291 301 source: repository object or URL
292 302
293 303 dest: URL of destination repository to create (defaults to base
294 304 name of source repository)
295 305
296 306 pull: always pull from source repository, even in local case or if the
297 307 server prefers streaming
298 308
299 309 stream: stream raw data uncompressed from repository (fast over
300 310 LAN, slow over WAN)
301 311
302 312 rev: revision to clone up to (implies pull=True)
303 313
304 314 update: update working directory after clone completes, if
305 315 destination is local repository (True means update to default rev,
306 316 anything else is treated as a revision)
307 317
308 318 branch: branches to clone
309 319 """
310 320
311 321 if isinstance(source, str):
312 322 origsource = ui.expandpath(source)
313 323 source, branch = parseurl(origsource, branch)
314 324 srcpeer = peer(ui, peeropts, source)
315 325 else:
316 326 srcpeer = source.peer() # in case we were called with a localrepo
317 327 branch = (None, branch or [])
318 328 origsource = source = srcpeer.url()
319 329 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
320 330
321 331 if dest is None:
322 332 dest = defaultdest(source)
323 333 if dest:
324 334 ui.status(_("destination directory: %s\n") % dest)
325 335 else:
326 336 dest = ui.expandpath(dest)
327 337
328 338 dest = util.urllocalpath(dest)
329 339 source = util.urllocalpath(source)
330 340
331 341 if not dest:
332 342 raise util.Abort(_("empty destination path is not valid"))
333 343
334 344 destvfs = scmutil.vfs(dest, expandpath=True)
335 345 if destvfs.lexists():
336 346 if not destvfs.isdir():
337 347 raise util.Abort(_("destination '%s' already exists") % dest)
338 348 elif destvfs.listdir():
339 349 raise util.Abort(_("destination '%s' is not empty") % dest)
340 350
341 351 srclock = destlock = cleandir = None
342 352 srcrepo = srcpeer.local()
343 353 try:
344 354 abspath = origsource
345 355 if islocal(origsource):
346 356 abspath = os.path.abspath(util.urllocalpath(origsource))
347 357
348 358 if islocal(dest):
349 359 cleandir = dest
350 360
351 361 copy = False
352 362 if (srcrepo and srcrepo.cancopy() and islocal(dest)
353 363 and not phases.hassecret(srcrepo)):
354 364 copy = not pull and not rev
355 365
356 366 if copy:
357 367 try:
358 368 # we use a lock here because if we race with commit, we
359 369 # can end up with extra data in the cloned revlogs that's
360 370 # not pointed to by changesets, thus causing verify to
361 371 # fail
362 372 srclock = srcrepo.lock(wait=False)
363 373 except error.LockError:
364 374 copy = False
365 375
366 376 if copy:
367 377 srcrepo.hook('preoutgoing', throw=True, source='clone')
368 378 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
369 379 if not os.path.exists(dest):
370 380 os.mkdir(dest)
371 381 else:
372 382 # only clean up directories we create ourselves
373 383 cleandir = hgdir
374 384 try:
375 385 destpath = hgdir
376 386 util.makedir(destpath, notindexed=True)
377 387 except OSError, inst:
378 388 if inst.errno == errno.EEXIST:
379 389 cleandir = None
380 390 raise util.Abort(_("destination '%s' already exists")
381 391 % dest)
382 392 raise
383 393
384 394 destlock = copystore(ui, srcrepo, destpath)
385 395 # copy bookmarks over
386 396 srcbookmarks = srcrepo.join('bookmarks')
387 397 dstbookmarks = os.path.join(destpath, 'bookmarks')
388 398 if os.path.exists(srcbookmarks):
389 399 util.copyfile(srcbookmarks, dstbookmarks)
390 400
391 401 # Recomputing branch cache might be slow on big repos,
392 402 # so just copy it
393 403 def copybranchcache(fname):
394 404 srcbranchcache = srcrepo.join('cache/%s' % fname)
395 405 dstbranchcache = os.path.join(dstcachedir, fname)
396 406 if os.path.exists(srcbranchcache):
397 407 if not os.path.exists(dstcachedir):
398 408 os.mkdir(dstcachedir)
399 409 util.copyfile(srcbranchcache, dstbranchcache)
400 410
401 411 dstcachedir = os.path.join(destpath, 'cache')
402 412 # In local clones we're copying all nodes, not just served
403 413 # ones. Therefore copy all branch caches over.
404 414 copybranchcache('branch2')
405 415 for cachename in repoview.filtertable:
406 416 copybranchcache('branch2-%s' % cachename)
407 417
408 418 # we need to re-init the repo after manually copying the data
409 419 # into it
410 420 destpeer = peer(srcrepo, peeropts, dest)
411 421 srcrepo.hook('outgoing', source='clone',
412 422 node=node.hex(node.nullid))
413 423 else:
414 424 try:
415 425 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
416 426 # only pass ui when no srcrepo
417 427 except OSError, inst:
418 428 if inst.errno == errno.EEXIST:
419 429 cleandir = None
420 430 raise util.Abort(_("destination '%s' already exists")
421 431 % dest)
422 432 raise
423 433
424 434 revs = None
425 435 if rev:
426 436 if not srcpeer.capable('lookup'):
427 437 raise util.Abort(_("src repository does not support "
428 438 "revision lookup and so doesn't "
429 439 "support clone by revision"))
430 440 revs = [srcpeer.lookup(r) for r in rev]
431 441 checkout = revs[0]
432 442 if destpeer.local():
433 443 if not stream:
434 444 if pull:
435 445 stream = False
436 446 else:
437 447 stream = None
438 448 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
439 449 elif srcrepo:
440 450 exchange.push(srcrepo, destpeer, revs=revs,
441 451 bookmarks=srcrepo._bookmarks.keys())
442 452 else:
443 453 raise util.Abort(_("clone from remote to remote not supported"))
444 454
445 455 cleandir = None
446 456
447 457 destrepo = destpeer.local()
448 458 if destrepo:
449 459 template = uimod.samplehgrcs['cloned']
450 460 fp = destrepo.vfs("hgrc", "w", text=True)
451 461 u = util.url(abspath)
452 462 u.passwd = None
453 463 defaulturl = str(u)
454 464 fp.write(template % defaulturl)
455 465 fp.close()
456 466
457 467 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
458 468
459 469 if update:
460 470 if update is not True:
461 471 checkout = srcpeer.lookup(update)
462 472 uprev = None
463 473 status = None
464 474 if checkout is not None:
465 475 try:
466 476 uprev = destrepo.lookup(checkout)
467 477 except error.RepoLookupError:
468 478 pass
469 479 if uprev is None:
470 480 try:
471 481 uprev = destrepo._bookmarks['@']
472 482 update = '@'
473 483 bn = destrepo[uprev].branch()
474 484 if bn == 'default':
475 485 status = _("updating to bookmark @\n")
476 486 else:
477 487 status = (_("updating to bookmark @ on branch %s\n")
478 488 % bn)
479 489 except KeyError:
480 490 try:
481 491 uprev = destrepo.branchtip('default')
482 492 except error.RepoLookupError:
483 493 uprev = destrepo.lookup('tip')
484 494 if not status:
485 495 bn = destrepo[uprev].branch()
486 496 status = _("updating to branch %s\n") % bn
487 497 destrepo.ui.status(status)
488 498 _update(destrepo, uprev)
489 499 if update in destrepo._bookmarks:
490 500 bookmarks.setcurrent(destrepo, update)
491 501 finally:
492 502 release(srclock, destlock)
493 503 if cleandir is not None:
494 504 shutil.rmtree(cleandir, True)
495 505 if srcpeer is not None:
496 506 srcpeer.close()
497 507 return srcpeer, destpeer
498 508
499 509 def _showstats(repo, stats):
500 510 repo.ui.status(_("%d files updated, %d files merged, "
501 511 "%d files removed, %d files unresolved\n") % stats)
502 512
503 513 def updaterepo(repo, node, overwrite):
504 514 """Update the working directory to node.
505 515
506 516 When overwrite is set, changes are clobbered, merged else
507 517
508 518 returns stats (see pydoc mercurial.merge.applyupdates)"""
509 519 return mergemod.update(repo, node, False, overwrite, None,
510 520 labels=['working copy', 'destination'])
511 521
512 522 def update(repo, node):
513 523 """update the working directory to node, merging linear changes"""
514 524 stats = updaterepo(repo, node, False)
515 525 _showstats(repo, stats)
516 526 if stats[3]:
517 527 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
518 528 return stats[3] > 0
519 529
520 530 # naming conflict in clone()
521 531 _update = update
522 532
523 533 def clean(repo, node, show_stats=True):
524 534 """forcibly switch the working directory to node, clobbering changes"""
525 535 stats = updaterepo(repo, node, True)
526 536 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
527 537 if show_stats:
528 538 _showstats(repo, stats)
529 539 return stats[3] > 0
530 540
531 541 def merge(repo, node, force=None, remind=True):
532 542 """Branch merge with node, resolving changes. Return true if any
533 543 unresolved conflicts."""
534 544 stats = mergemod.update(repo, node, True, force, False)
535 545 _showstats(repo, stats)
536 546 if stats[3]:
537 547 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
538 548 "or 'hg update -C .' to abandon\n"))
539 549 elif remind:
540 550 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
541 551 return stats[3] > 0
542 552
543 553 def _incoming(displaychlist, subreporecurse, ui, repo, source,
544 554 opts, buffered=False):
545 555 """
546 556 Helper for incoming / gincoming.
547 557 displaychlist gets called with
548 558 (remoterepo, incomingchangesetlist, displayer) parameters,
549 559 and is supposed to contain only code that can't be unified.
550 560 """
551 561 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
552 562 other = peer(repo, opts, source)
553 563 ui.status(_('comparing with %s\n') % util.hidepassword(source))
554 564 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
555 565
556 566 if revs:
557 567 revs = [other.lookup(rev) for rev in revs]
558 568 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
559 569 revs, opts["bundle"], opts["force"])
560 570 try:
561 571 if not chlist:
562 572 ui.status(_("no changes found\n"))
563 573 return subreporecurse()
564 574
565 575 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
566 576 displaychlist(other, chlist, displayer)
567 577 displayer.close()
568 578 finally:
569 579 cleanupfn()
570 580 subreporecurse()
571 581 return 0 # exit code is zero since we found incoming changes
572 582
573 583 def incoming(ui, repo, source, opts):
574 584 def subreporecurse():
575 585 ret = 1
576 586 if opts.get('subrepos'):
577 587 ctx = repo[None]
578 588 for subpath in sorted(ctx.substate):
579 589 sub = ctx.sub(subpath)
580 590 ret = min(ret, sub.incoming(ui, source, opts))
581 591 return ret
582 592
583 593 def display(other, chlist, displayer):
584 594 limit = cmdutil.loglimit(opts)
585 595 if opts.get('newest_first'):
586 596 chlist.reverse()
587 597 count = 0
588 598 for n in chlist:
589 599 if limit is not None and count >= limit:
590 600 break
591 601 parents = [p for p in other.changelog.parents(n) if p != nullid]
592 602 if opts.get('no_merges') and len(parents) == 2:
593 603 continue
594 604 count += 1
595 605 displayer.show(other[n])
596 606 return _incoming(display, subreporecurse, ui, repo, source, opts)
597 607
598 608 def _outgoing(ui, repo, dest, opts):
599 609 dest = ui.expandpath(dest or 'default-push', dest or 'default')
600 610 dest, branches = parseurl(dest, opts.get('branch'))
601 611 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
602 612 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
603 613 if revs:
604 614 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
605 615
606 616 other = peer(repo, opts, dest)
607 617 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
608 618 force=opts.get('force'))
609 619 o = outgoing.missing
610 620 if not o:
611 621 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
612 622 return o, other
613 623
614 624 def outgoing(ui, repo, dest, opts):
615 625 def recurse():
616 626 ret = 1
617 627 if opts.get('subrepos'):
618 628 ctx = repo[None]
619 629 for subpath in sorted(ctx.substate):
620 630 sub = ctx.sub(subpath)
621 631 ret = min(ret, sub.outgoing(ui, dest, opts))
622 632 return ret
623 633
624 634 limit = cmdutil.loglimit(opts)
625 635 o, other = _outgoing(ui, repo, dest, opts)
626 636 if not o:
627 637 cmdutil.outgoinghooks(ui, repo, other, opts, o)
628 638 return recurse()
629 639
630 640 if opts.get('newest_first'):
631 641 o.reverse()
632 642 displayer = cmdutil.show_changeset(ui, repo, opts)
633 643 count = 0
634 644 for n in o:
635 645 if limit is not None and count >= limit:
636 646 break
637 647 parents = [p for p in repo.changelog.parents(n) if p != nullid]
638 648 if opts.get('no_merges') and len(parents) == 2:
639 649 continue
640 650 count += 1
641 651 displayer.show(repo[n])
642 652 displayer.close()
643 653 cmdutil.outgoinghooks(ui, repo, other, opts, o)
644 654 recurse()
645 655 return 0 # exit code is zero since we found outgoing changes
646 656
647 657 def revert(repo, node, choose):
648 658 """revert changes to revision in node without updating dirstate"""
649 659 return mergemod.update(repo, node, False, True, choose)[3] > 0
650 660
651 661 def verify(repo):
652 662 """verify the consistency of a repository"""
653 663 return verifymod.verify(repo)
654 664
655 665 def remoteui(src, opts):
656 666 'build a remote ui from ui or repo and opts'
657 667 if util.safehasattr(src, 'baseui'): # looks like a repository
658 668 dst = src.baseui.copy() # drop repo-specific config
659 669 src = src.ui # copy target options from repo
660 670 else: # assume it's a global ui object
661 671 dst = src.copy() # keep all global options
662 672
663 673 # copy ssh-specific options
664 674 for o in 'ssh', 'remotecmd':
665 675 v = opts.get(o) or src.config('ui', o)
666 676 if v:
667 677 dst.setconfig("ui", o, v, 'copied')
668 678
669 679 # copy bundle-specific options
670 680 r = src.config('bundle', 'mainreporoot')
671 681 if r:
672 682 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
673 683
674 684 # copy selected local settings to the remote ui
675 685 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
676 686 for key, val in src.configitems(sect):
677 687 dst.setconfig(sect, key, val, 'copied')
678 688 v = src.config('web', 'cacerts')
679 689 if v == '!':
680 690 dst.setconfig('web', 'cacerts', v, 'copied')
681 691 elif v:
682 692 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
683 693
684 694 return dst
@@ -1,662 +1,670 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 Trigger branchcache creation:
29 29
30 30 $ hg branches
31 31 default 10:a7949464abda
32 32 $ ls .hg/cache
33 33 branch2-served
34 34 rbc-names-v1
35 35 rbc-revs-v1
36 36
37 37 Default operation:
38 38
39 39 $ hg clone . ../b
40 40 updating to branch default
41 41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 42 $ cd ../b
43 43
44 44 Ensure branchcache got copied over:
45 45
46 46 $ ls .hg/cache
47 47 branch2-served
48 48
49 49 $ cat a
50 50 a
51 51 $ hg verify
52 52 checking changesets
53 53 checking manifests
54 54 crosschecking files in changesets and manifests
55 55 checking files
56 56 2 files, 11 changesets, 11 total revisions
57 57
58 58 Invalid dest '' must abort:
59 59
60 60 $ hg clone . ''
61 61 abort: empty destination path is not valid
62 62 [255]
63 63
64 64 No update, with debug option:
65 65
66 66 #if hardlink
67 67 $ hg --debug clone -U . ../c
68 linking: 1
69 linking: 2
70 linking: 3
71 linking: 4
72 linking: 5
73 linking: 6
74 linking: 7
75 linking: 8
68 76 linked 8 files
69 77 #else
70 78 $ hg --debug clone -U . ../c
71 79 copied 8 files
72 80 #endif
73 81 $ cd ../c
74 82
75 83 Ensure branchcache got copied over:
76 84
77 85 $ ls .hg/cache
78 86 branch2-served
79 87
80 88 $ cat a 2>/dev/null || echo "a not present"
81 89 a not present
82 90 $ hg verify
83 91 checking changesets
84 92 checking manifests
85 93 crosschecking files in changesets and manifests
86 94 checking files
87 95 2 files, 11 changesets, 11 total revisions
88 96
89 97 Default destination:
90 98
91 99 $ mkdir ../d
92 100 $ cd ../d
93 101 $ hg clone ../a
94 102 destination directory: a
95 103 updating to branch default
96 104 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 105 $ cd a
98 106 $ hg cat a
99 107 a
100 108 $ cd ../..
101 109
102 110 Check that we drop the 'file:' from the path before writing the .hgrc:
103 111
104 112 $ hg clone file:a e
105 113 updating to branch default
106 114 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 115 $ grep 'file:' e/.hg/hgrc
108 116 [1]
109 117
110 118 Check that path aliases are expanded:
111 119
112 120 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
113 121 $ hg -R f showconfig paths.default
114 122 $TESTTMP/a#0 (glob)
115 123
116 124 Use --pull:
117 125
118 126 $ hg clone --pull a g
119 127 requesting all changes
120 128 adding changesets
121 129 adding manifests
122 130 adding file changes
123 131 added 11 changesets with 11 changes to 2 files
124 132 updating to branch default
125 133 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 134 $ hg -R g verify
127 135 checking changesets
128 136 checking manifests
129 137 crosschecking files in changesets and manifests
130 138 checking files
131 139 2 files, 11 changesets, 11 total revisions
132 140
133 141 Invalid dest '' with --pull must abort (issue2528):
134 142
135 143 $ hg clone --pull a ''
136 144 abort: empty destination path is not valid
137 145 [255]
138 146
139 147 Clone to '.':
140 148
141 149 $ mkdir h
142 150 $ cd h
143 151 $ hg clone ../a .
144 152 updating to branch default
145 153 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 154 $ cd ..
147 155
148 156
149 157 *** Tests for option -u ***
150 158
151 159 Adding some more history to repo a:
152 160
153 161 $ cd a
154 162 $ hg tag ref1
155 163 $ echo the quick brown fox >a
156 164 $ hg ci -m "hacked default"
157 165 $ hg up ref1
158 166 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
159 167 $ hg branch stable
160 168 marked working directory as branch stable
161 169 (branches are permanent and global, did you want a bookmark?)
162 170 $ echo some text >a
163 171 $ hg ci -m "starting branch stable"
164 172 $ hg tag ref2
165 173 $ echo some more text >a
166 174 $ hg ci -m "another change for branch stable"
167 175 $ hg up ref2
168 176 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
169 177 $ hg parents
170 178 changeset: 13:e8ece76546a6
171 179 branch: stable
172 180 tag: ref2
173 181 parent: 10:a7949464abda
174 182 user: test
175 183 date: Thu Jan 01 00:00:00 1970 +0000
176 184 summary: starting branch stable
177 185
178 186
179 187 Repo a has two heads:
180 188
181 189 $ hg heads
182 190 changeset: 15:0aae7cf88f0d
183 191 branch: stable
184 192 tag: tip
185 193 user: test
186 194 date: Thu Jan 01 00:00:00 1970 +0000
187 195 summary: another change for branch stable
188 196
189 197 changeset: 12:f21241060d6a
190 198 user: test
191 199 date: Thu Jan 01 00:00:00 1970 +0000
192 200 summary: hacked default
193 201
194 202
195 203 $ cd ..
196 204
197 205
198 206 Testing --noupdate with --updaterev (must abort):
199 207
200 208 $ hg clone --noupdate --updaterev 1 a ua
201 209 abort: cannot specify both --noupdate and --updaterev
202 210 [255]
203 211
204 212
205 213 Testing clone -u:
206 214
207 215 $ hg clone -u . a ua
208 216 updating to branch stable
209 217 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 218
211 219 Repo ua has both heads:
212 220
213 221 $ hg -R ua heads
214 222 changeset: 15:0aae7cf88f0d
215 223 branch: stable
216 224 tag: tip
217 225 user: test
218 226 date: Thu Jan 01 00:00:00 1970 +0000
219 227 summary: another change for branch stable
220 228
221 229 changeset: 12:f21241060d6a
222 230 user: test
223 231 date: Thu Jan 01 00:00:00 1970 +0000
224 232 summary: hacked default
225 233
226 234
227 235 Same revision checked out in repo a and ua:
228 236
229 237 $ hg -R a parents --template "{node|short}\n"
230 238 e8ece76546a6
231 239 $ hg -R ua parents --template "{node|short}\n"
232 240 e8ece76546a6
233 241
234 242 $ rm -r ua
235 243
236 244
237 245 Testing clone --pull -u:
238 246
239 247 $ hg clone --pull -u . a ua
240 248 requesting all changes
241 249 adding changesets
242 250 adding manifests
243 251 adding file changes
244 252 added 16 changesets with 16 changes to 3 files (+1 heads)
245 253 updating to branch stable
246 254 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 255
248 256 Repo ua has both heads:
249 257
250 258 $ hg -R ua heads
251 259 changeset: 15:0aae7cf88f0d
252 260 branch: stable
253 261 tag: tip
254 262 user: test
255 263 date: Thu Jan 01 00:00:00 1970 +0000
256 264 summary: another change for branch stable
257 265
258 266 changeset: 12:f21241060d6a
259 267 user: test
260 268 date: Thu Jan 01 00:00:00 1970 +0000
261 269 summary: hacked default
262 270
263 271
264 272 Same revision checked out in repo a and ua:
265 273
266 274 $ hg -R a parents --template "{node|short}\n"
267 275 e8ece76546a6
268 276 $ hg -R ua parents --template "{node|short}\n"
269 277 e8ece76546a6
270 278
271 279 $ rm -r ua
272 280
273 281
274 282 Testing clone -u <branch>:
275 283
276 284 $ hg clone -u stable a ua
277 285 updating to branch stable
278 286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 287
280 288 Repo ua has both heads:
281 289
282 290 $ hg -R ua heads
283 291 changeset: 15:0aae7cf88f0d
284 292 branch: stable
285 293 tag: tip
286 294 user: test
287 295 date: Thu Jan 01 00:00:00 1970 +0000
288 296 summary: another change for branch stable
289 297
290 298 changeset: 12:f21241060d6a
291 299 user: test
292 300 date: Thu Jan 01 00:00:00 1970 +0000
293 301 summary: hacked default
294 302
295 303
296 304 Branch 'stable' is checked out:
297 305
298 306 $ hg -R ua parents
299 307 changeset: 15:0aae7cf88f0d
300 308 branch: stable
301 309 tag: tip
302 310 user: test
303 311 date: Thu Jan 01 00:00:00 1970 +0000
304 312 summary: another change for branch stable
305 313
306 314
307 315 $ rm -r ua
308 316
309 317
310 318 Testing default checkout:
311 319
312 320 $ hg clone a ua
313 321 updating to branch default
314 322 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 323
316 324 Repo ua has both heads:
317 325
318 326 $ hg -R ua heads
319 327 changeset: 15:0aae7cf88f0d
320 328 branch: stable
321 329 tag: tip
322 330 user: test
323 331 date: Thu Jan 01 00:00:00 1970 +0000
324 332 summary: another change for branch stable
325 333
326 334 changeset: 12:f21241060d6a
327 335 user: test
328 336 date: Thu Jan 01 00:00:00 1970 +0000
329 337 summary: hacked default
330 338
331 339
332 340 Branch 'default' is checked out:
333 341
334 342 $ hg -R ua parents
335 343 changeset: 12:f21241060d6a
336 344 user: test
337 345 date: Thu Jan 01 00:00:00 1970 +0000
338 346 summary: hacked default
339 347
340 348 Test clone with a branch named "@" (issue3677)
341 349
342 350 $ hg -R ua branch @
343 351 marked working directory as branch @
344 352 (branches are permanent and global, did you want a bookmark?)
345 353 $ hg -R ua commit -m 'created branch @'
346 354 $ hg clone ua atbranch
347 355 updating to branch default
348 356 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 357 $ hg -R atbranch heads
350 358 changeset: 16:798b6d97153e
351 359 branch: @
352 360 tag: tip
353 361 parent: 12:f21241060d6a
354 362 user: test
355 363 date: Thu Jan 01 00:00:00 1970 +0000
356 364 summary: created branch @
357 365
358 366 changeset: 15:0aae7cf88f0d
359 367 branch: stable
360 368 user: test
361 369 date: Thu Jan 01 00:00:00 1970 +0000
362 370 summary: another change for branch stable
363 371
364 372 changeset: 12:f21241060d6a
365 373 user: test
366 374 date: Thu Jan 01 00:00:00 1970 +0000
367 375 summary: hacked default
368 376
369 377 $ hg -R atbranch parents
370 378 changeset: 12:f21241060d6a
371 379 user: test
372 380 date: Thu Jan 01 00:00:00 1970 +0000
373 381 summary: hacked default
374 382
375 383
376 384 $ rm -r ua atbranch
377 385
378 386
379 387 Testing #<branch>:
380 388
381 389 $ hg clone -u . a#stable ua
382 390 adding changesets
383 391 adding manifests
384 392 adding file changes
385 393 added 14 changesets with 14 changes to 3 files
386 394 updating to branch stable
387 395 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 396
389 397 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
390 398
391 399 $ hg -R ua heads
392 400 changeset: 13:0aae7cf88f0d
393 401 branch: stable
394 402 tag: tip
395 403 user: test
396 404 date: Thu Jan 01 00:00:00 1970 +0000
397 405 summary: another change for branch stable
398 406
399 407 changeset: 10:a7949464abda
400 408 user: test
401 409 date: Thu Jan 01 00:00:00 1970 +0000
402 410 summary: test
403 411
404 412
405 413 Same revision checked out in repo a and ua:
406 414
407 415 $ hg -R a parents --template "{node|short}\n"
408 416 e8ece76546a6
409 417 $ hg -R ua parents --template "{node|short}\n"
410 418 e8ece76546a6
411 419
412 420 $ rm -r ua
413 421
414 422
415 423 Testing -u -r <branch>:
416 424
417 425 $ hg clone -u . -r stable a ua
418 426 adding changesets
419 427 adding manifests
420 428 adding file changes
421 429 added 14 changesets with 14 changes to 3 files
422 430 updating to branch stable
423 431 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
424 432
425 433 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
426 434
427 435 $ hg -R ua heads
428 436 changeset: 13:0aae7cf88f0d
429 437 branch: stable
430 438 tag: tip
431 439 user: test
432 440 date: Thu Jan 01 00:00:00 1970 +0000
433 441 summary: another change for branch stable
434 442
435 443 changeset: 10:a7949464abda
436 444 user: test
437 445 date: Thu Jan 01 00:00:00 1970 +0000
438 446 summary: test
439 447
440 448
441 449 Same revision checked out in repo a and ua:
442 450
443 451 $ hg -R a parents --template "{node|short}\n"
444 452 e8ece76546a6
445 453 $ hg -R ua parents --template "{node|short}\n"
446 454 e8ece76546a6
447 455
448 456 $ rm -r ua
449 457
450 458
451 459 Testing -r <branch>:
452 460
453 461 $ hg clone -r stable a ua
454 462 adding changesets
455 463 adding manifests
456 464 adding file changes
457 465 added 14 changesets with 14 changes to 3 files
458 466 updating to branch stable
459 467 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
460 468
461 469 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
462 470
463 471 $ hg -R ua heads
464 472 changeset: 13:0aae7cf88f0d
465 473 branch: stable
466 474 tag: tip
467 475 user: test
468 476 date: Thu Jan 01 00:00:00 1970 +0000
469 477 summary: another change for branch stable
470 478
471 479 changeset: 10:a7949464abda
472 480 user: test
473 481 date: Thu Jan 01 00:00:00 1970 +0000
474 482 summary: test
475 483
476 484
477 485 Branch 'stable' is checked out:
478 486
479 487 $ hg -R ua parents
480 488 changeset: 13:0aae7cf88f0d
481 489 branch: stable
482 490 tag: tip
483 491 user: test
484 492 date: Thu Jan 01 00:00:00 1970 +0000
485 493 summary: another change for branch stable
486 494
487 495
488 496 $ rm -r ua
489 497
490 498
491 499 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
492 500 iterable in addbranchrevs()
493 501
494 502 $ cat <<EOF > simpleclone.py
495 503 > from mercurial import ui, hg
496 504 > myui = ui.ui()
497 505 > repo = hg.repository(myui, 'a')
498 506 > hg.clone(myui, {}, repo, dest="ua")
499 507 > EOF
500 508
501 509 $ python simpleclone.py
502 510 updating to branch default
503 511 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 512
505 513 $ rm -r ua
506 514
507 515 $ cat <<EOF > branchclone.py
508 516 > from mercurial import ui, hg, extensions
509 517 > myui = ui.ui()
510 518 > extensions.loadall(myui)
511 519 > repo = hg.repository(myui, 'a')
512 520 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
513 521 > EOF
514 522
515 523 $ python branchclone.py
516 524 adding changesets
517 525 adding manifests
518 526 adding file changes
519 527 added 14 changesets with 14 changes to 3 files
520 528 updating to branch stable
521 529 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
522 530 $ rm -r ua
523 531
524 532
525 533 Test clone with special '@' bookmark:
526 534 $ cd a
527 535 $ hg bookmark -r a7949464abda @ # branch point of stable from default
528 536 $ hg clone . ../i
529 537 updating to bookmark @
530 538 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
531 539 $ hg id -i ../i
532 540 a7949464abda
533 541 $ rm -r ../i
534 542
535 543 $ hg bookmark -f -r stable @
536 544 $ hg bookmarks
537 545 @ 15:0aae7cf88f0d
538 546 $ hg clone . ../i
539 547 updating to bookmark @ on branch stable
540 548 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
541 549 $ hg id -i ../i
542 550 0aae7cf88f0d
543 551 $ cd "$TESTTMP"
544 552
545 553
546 554 Testing failures:
547 555
548 556 $ mkdir fail
549 557 $ cd fail
550 558
551 559 No local source
552 560
553 561 $ hg clone a b
554 562 abort: repository a not found!
555 563 [255]
556 564
557 565 No remote source
558 566
559 567 #if windows
560 568 $ hg clone http://127.0.0.1:3121/a b
561 569 abort: error: * (glob)
562 570 [255]
563 571 #else
564 572 $ hg clone http://127.0.0.1:3121/a b
565 573 abort: error: *refused* (glob)
566 574 [255]
567 575 #endif
568 576 $ rm -rf b # work around bug with http clone
569 577
570 578
571 579 #if unix-permissions no-root
572 580
573 581 Inaccessible source
574 582
575 583 $ mkdir a
576 584 $ chmod 000 a
577 585 $ hg clone a b
578 586 abort: repository a not found!
579 587 [255]
580 588
581 589 Inaccessible destination
582 590
583 591 $ hg init b
584 592 $ cd b
585 593 $ hg clone . ../a
586 594 abort: Permission denied: '../a'
587 595 [255]
588 596 $ cd ..
589 597 $ chmod 700 a
590 598 $ rm -r a b
591 599
592 600 #endif
593 601
594 602
595 603 #if fifo
596 604
597 605 Source of wrong type
598 606
599 607 $ mkfifo a
600 608 $ hg clone a b
601 609 abort: repository a not found!
602 610 [255]
603 611 $ rm a
604 612
605 613 #endif
606 614
607 615 Default destination, same directory
608 616
609 617 $ hg init q
610 618 $ hg clone q
611 619 destination directory: q
612 620 abort: destination 'q' is not empty
613 621 [255]
614 622
615 623 destination directory not empty
616 624
617 625 $ mkdir a
618 626 $ echo stuff > a/a
619 627 $ hg clone q a
620 628 abort: destination 'a' is not empty
621 629 [255]
622 630
623 631
624 632 #if unix-permissions no-root
625 633
626 634 leave existing directory in place after clone failure
627 635
628 636 $ hg init c
629 637 $ cd c
630 638 $ echo c > c
631 639 $ hg commit -A -m test
632 640 adding c
633 641 $ chmod -rx .hg/store/data
634 642 $ cd ..
635 643 $ mkdir d
636 644 $ hg clone c d 2> err
637 645 [255]
638 646 $ test -d d
639 647 $ test -d d/.hg
640 648 [1]
641 649
642 650 re-enable perm to allow deletion
643 651
644 652 $ chmod +rx c/.hg/store/data
645 653
646 654 #endif
647 655
648 656 $ cd ..
649 657
650 658 Test clone from the repository in (emulated) revlog format 0 (issue4203):
651 659
652 660 $ mkdir issue4203
653 661 $ mkdir -p src/.hg
654 662 $ echo foo > src/foo
655 663 $ hg -R src add src/foo
656 664 $ hg -R src commit -m '#0'
657 665 $ hg -R src log -q
658 666 0:e1bab28bca43
659 667 $ hg clone -U -q src dst
660 668 $ hg -R dst log -q
661 669 0:e1bab28bca43
662 670 $ cd ..
@@ -1,367 +1,374 b''
1 1 #require hardlink
2 2
3 3 $ cat > nlinks.py <<EOF
4 4 > import sys
5 5 > from mercurial import util
6 6 > for f in sorted(sys.stdin.readlines()):
7 7 > f = f[:-1]
8 8 > print util.nlinks(f), f
9 9 > EOF
10 10
11 11 $ nlinksdir()
12 12 > {
13 13 > find $1 -type f | python $TESTTMP/nlinks.py
14 14 > }
15 15
16 16 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
17 17
18 18 $ cat > linkcp.py <<EOF
19 19 > from mercurial import util
20 20 > import sys
21 21 > util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
22 22 > EOF
23 23
24 24 $ linkcp()
25 25 > {
26 26 > python $TESTTMP/linkcp.py $1 $2
27 27 > }
28 28
29 29 Prepare repo r1:
30 30
31 31 $ hg init r1
32 32 $ cd r1
33 33
34 34 $ echo c1 > f1
35 35 $ hg add f1
36 36 $ hg ci -m0
37 37
38 38 $ mkdir d1
39 39 $ cd d1
40 40 $ echo c2 > f2
41 41 $ hg add f2
42 42 $ hg ci -m1
43 43 $ cd ../..
44 44
45 45 $ nlinksdir r1/.hg/store
46 46 1 r1/.hg/store/00changelog.i
47 47 1 r1/.hg/store/00manifest.i
48 48 1 r1/.hg/store/data/d1/f2.i
49 49 1 r1/.hg/store/data/f1.i
50 50 1 r1/.hg/store/fncache
51 51 1 r1/.hg/store/phaseroots
52 52 1 r1/.hg/store/undo
53 53 1 r1/.hg/store/undo.backup.fncache
54 54 1 r1/.hg/store/undo.backupfiles
55 55 1 r1/.hg/store/undo.phaseroots
56 56
57 57
58 58 Create hardlinked clone r2:
59 59
60 60 $ hg clone -U --debug r1 r2
61 linking: 1
62 linking: 2
63 linking: 3
64 linking: 4
65 linking: 5
66 linking: 6
67 linking: 7
61 68 linked 7 files
62 69
63 70 Create non-hardlinked clone r3:
64 71
65 72 $ hg clone --pull r1 r3
66 73 requesting all changes
67 74 adding changesets
68 75 adding manifests
69 76 adding file changes
70 77 added 2 changesets with 2 changes to 2 files
71 78 updating to branch default
72 79 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 80
74 81
75 82 Repos r1 and r2 should now contain hardlinked files:
76 83
77 84 $ nlinksdir r1/.hg/store
78 85 2 r1/.hg/store/00changelog.i
79 86 2 r1/.hg/store/00manifest.i
80 87 2 r1/.hg/store/data/d1/f2.i
81 88 2 r1/.hg/store/data/f1.i
82 89 2 r1/.hg/store/fncache
83 90 1 r1/.hg/store/phaseroots
84 91 1 r1/.hg/store/undo
85 92 1 r1/.hg/store/undo.backup.fncache
86 93 1 r1/.hg/store/undo.backupfiles
87 94 1 r1/.hg/store/undo.phaseroots
88 95
89 96 $ nlinksdir r2/.hg/store
90 97 2 r2/.hg/store/00changelog.i
91 98 2 r2/.hg/store/00manifest.i
92 99 2 r2/.hg/store/data/d1/f2.i
93 100 2 r2/.hg/store/data/f1.i
94 101 2 r2/.hg/store/fncache
95 102
96 103 Repo r3 should not be hardlinked:
97 104
98 105 $ nlinksdir r3/.hg/store
99 106 1 r3/.hg/store/00changelog.i
100 107 1 r3/.hg/store/00manifest.i
101 108 1 r3/.hg/store/data/d1/f2.i
102 109 1 r3/.hg/store/data/f1.i
103 110 1 r3/.hg/store/fncache
104 111 1 r3/.hg/store/phaseroots
105 112 1 r3/.hg/store/undo
106 113 1 r3/.hg/store/undo.backupfiles
107 114 1 r3/.hg/store/undo.phaseroots
108 115
109 116
110 117 Create a non-inlined filelog in r3:
111 118
112 119 $ cd r3/d1
113 120 >>> f = open('data1', 'wb')
114 121 >>> for x in range(10000):
115 122 ... f.write("%s\n" % str(x))
116 123 >>> f.close()
117 124 $ for j in 0 1 2 3 4 5 6 7 8 9; do
118 125 > cat data1 >> f2
119 126 > hg commit -m$j
120 127 > done
121 128 $ cd ../..
122 129
123 130 $ nlinksdir r3/.hg/store
124 131 1 r3/.hg/store/00changelog.i
125 132 1 r3/.hg/store/00manifest.i
126 133 1 r3/.hg/store/data/d1/f2.d
127 134 1 r3/.hg/store/data/d1/f2.i
128 135 1 r3/.hg/store/data/f1.i
129 136 1 r3/.hg/store/fncache
130 137 1 r3/.hg/store/phaseroots
131 138 1 r3/.hg/store/undo
132 139 1 r3/.hg/store/undo.backup.fncache
133 140 1 r3/.hg/store/undo.backup.phaseroots
134 141 1 r3/.hg/store/undo.backupfiles
135 142 1 r3/.hg/store/undo.phaseroots
136 143
137 144 Push to repo r1 should break up most hardlinks in r2:
138 145
139 146 $ hg -R r2 verify
140 147 checking changesets
141 148 checking manifests
142 149 crosschecking files in changesets and manifests
143 150 checking files
144 151 2 files, 2 changesets, 2 total revisions
145 152
146 153 $ cd r3
147 154 $ hg push
148 155 pushing to $TESTTMP/r1 (glob)
149 156 searching for changes
150 157 adding changesets
151 158 adding manifests
152 159 adding file changes
153 160 added 10 changesets with 10 changes to 1 files
154 161
155 162 $ cd ..
156 163
157 164 $ nlinksdir r2/.hg/store
158 165 1 r2/.hg/store/00changelog.i
159 166 1 r2/.hg/store/00manifest.i
160 167 1 r2/.hg/store/data/d1/f2.i
161 168 2 r2/.hg/store/data/f1.i
162 169 1 r2/.hg/store/fncache
163 170
164 171 $ hg -R r2 verify
165 172 checking changesets
166 173 checking manifests
167 174 crosschecking files in changesets and manifests
168 175 checking files
169 176 2 files, 2 changesets, 2 total revisions
170 177
171 178
172 179 $ cd r1
173 180 $ hg up
174 181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 182
176 183 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
177 184
178 185 $ echo c1c1 >> f1
179 186 $ hg ci -m00
180 187 $ cd ..
181 188
182 189 $ nlinksdir r2/.hg/store
183 190 1 r2/.hg/store/00changelog.i
184 191 1 r2/.hg/store/00manifest.i
185 192 1 r2/.hg/store/data/d1/f2.i
186 193 1 r2/.hg/store/data/f1.i
187 194 1 r2/.hg/store/fncache
188 195
189 196
190 197 $ cd r3
191 198 $ hg tip --template '{rev}:{node|short}\n'
192 199 11:a6451b6bc41f
193 200 $ echo bla > f1
194 201 $ hg ci -m1
195 202 $ cd ..
196 203
197 204 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
198 205
199 206 $ linkcp r3 r4
200 207
201 208 r4 has hardlinks in the working dir (not just inside .hg):
202 209
203 210 $ nlinksdir r4
204 211 2 r4/.hg/00changelog.i
205 212 2 r4/.hg/branch
206 213 2 r4/.hg/cache/branch2-served
207 214 2 r4/.hg/cache/rbc-names-v1
208 215 2 r4/.hg/cache/rbc-revs-v1
209 216 2 r4/.hg/dirstate
210 217 2 r4/.hg/hgrc
211 218 2 r4/.hg/last-message.txt
212 219 2 r4/.hg/requires
213 220 2 r4/.hg/store/00changelog.i
214 221 2 r4/.hg/store/00manifest.i
215 222 2 r4/.hg/store/data/d1/f2.d
216 223 2 r4/.hg/store/data/d1/f2.i
217 224 2 r4/.hg/store/data/f1.i
218 225 2 r4/.hg/store/fncache
219 226 2 r4/.hg/store/phaseroots
220 227 2 r4/.hg/store/undo
221 228 2 r4/.hg/store/undo.backup.fncache
222 229 2 r4/.hg/store/undo.backup.phaseroots
223 230 2 r4/.hg/store/undo.backupfiles
224 231 2 r4/.hg/store/undo.phaseroots
225 232 2 r4/.hg/undo.bookmarks
226 233 2 r4/.hg/undo.branch
227 234 2 r4/.hg/undo.desc
228 235 2 r4/.hg/undo.dirstate
229 236 2 r4/d1/data1
230 237 2 r4/d1/f2
231 238 2 r4/f1
232 239
233 240 Update back to revision 11 in r4 should break hardlink of file f1:
234 241
235 242 $ hg -R r4 up 11
236 243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
237 244
238 245 $ nlinksdir r4
239 246 2 r4/.hg/00changelog.i
240 247 1 r4/.hg/branch
241 248 2 r4/.hg/cache/branch2-served
242 249 2 r4/.hg/cache/rbc-names-v1
243 250 2 r4/.hg/cache/rbc-revs-v1
244 251 1 r4/.hg/dirstate
245 252 2 r4/.hg/hgrc
246 253 2 r4/.hg/last-message.txt
247 254 2 r4/.hg/requires
248 255 2 r4/.hg/store/00changelog.i
249 256 2 r4/.hg/store/00manifest.i
250 257 2 r4/.hg/store/data/d1/f2.d
251 258 2 r4/.hg/store/data/d1/f2.i
252 259 2 r4/.hg/store/data/f1.i
253 260 2 r4/.hg/store/fncache
254 261 2 r4/.hg/store/phaseroots
255 262 2 r4/.hg/store/undo
256 263 2 r4/.hg/store/undo.backup.fncache
257 264 2 r4/.hg/store/undo.backup.phaseroots
258 265 2 r4/.hg/store/undo.backupfiles
259 266 2 r4/.hg/store/undo.phaseroots
260 267 2 r4/.hg/undo.bookmarks
261 268 2 r4/.hg/undo.branch
262 269 2 r4/.hg/undo.desc
263 270 2 r4/.hg/undo.dirstate
264 271 2 r4/d1/data1
265 272 2 r4/d1/f2
266 273 1 r4/f1
267 274
268 275
269 276 Test hardlinking outside hg:
270 277
271 278 $ mkdir x
272 279 $ echo foo > x/a
273 280
274 281 $ linkcp x y
275 282 $ echo bar >> y/a
276 283
277 284 No diff if hardlink:
278 285
279 286 $ diff x/a y/a
280 287
281 288 Test mq hardlinking:
282 289
283 290 $ echo "[extensions]" >> $HGRCPATH
284 291 $ echo "mq=" >> $HGRCPATH
285 292
286 293 $ hg init a
287 294 $ cd a
288 295
289 296 $ hg qimport -n foo - << EOF
290 297 > # HG changeset patch
291 298 > # Date 1 0
292 299 > diff -r 2588a8b53d66 a
293 300 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
294 301 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
295 302 > @@ -0,0 +1,1 @@
296 303 > +a
297 304 > EOF
298 305 adding foo to series file
299 306
300 307 $ hg qpush
301 308 applying foo
302 309 now at: foo
303 310
304 311 $ cd ..
305 312 $ linkcp a b
306 313 $ cd b
307 314
308 315 $ hg qimport -n bar - << EOF
309 316 > # HG changeset patch
310 317 > # Date 2 0
311 318 > diff -r 2588a8b53d66 a
312 319 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
313 320 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
314 321 > @@ -0,0 +1,1 @@
315 322 > +b
316 323 > EOF
317 324 adding bar to series file
318 325
319 326 $ hg qpush
320 327 applying bar
321 328 now at: bar
322 329
323 330 $ cat .hg/patches/status
324 331 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
325 332 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
326 333
327 334 $ cat .hg/patches/series
328 335 foo
329 336 bar
330 337
331 338 $ cat ../a/.hg/patches/status
332 339 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
333 340
334 341 $ cat ../a/.hg/patches/series
335 342 foo
336 343
337 344 Test tags hardlinking:
338 345
339 346 $ hg qdel -r qbase:qtip
340 347 patch foo finalized without changeset message
341 348 patch bar finalized without changeset message
342 349
343 350 $ hg tag -l lfoo
344 351 $ hg tag foo
345 352
346 353 $ cd ..
347 354 $ linkcp b c
348 355 $ cd c
349 356
350 357 $ hg tag -l -r 0 lbar
351 358 $ hg tag -r 0 bar
352 359
353 360 $ cat .hgtags
354 361 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
355 362 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
356 363
357 364 $ cat .hg/localtags
358 365 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
359 366 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
360 367
361 368 $ cat ../b/.hgtags
362 369 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
363 370
364 371 $ cat ../b/.hg/localtags
365 372 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
366 373
367 374 $ cd ..
@@ -1,508 +1,536 b''
1 1 Create test repository:
2 2
3 3 $ hg init repo
4 4 $ cd repo
5 5 $ echo x1 > x.txt
6 6
7 7 $ hg init foo
8 8 $ cd foo
9 9 $ echo y1 > y.txt
10 10
11 11 $ hg init bar
12 12 $ cd bar
13 13 $ echo z1 > z.txt
14 14
15 15 $ cd ..
16 16 $ echo 'bar = bar' > .hgsub
17 17
18 18 $ cd ..
19 19 $ echo 'foo = foo' > .hgsub
20 20
21 21 Add files --- .hgsub files must go first to trigger subrepos:
22 22
23 23 $ hg add -S .hgsub
24 24 $ hg add -S foo/.hgsub
25 25 $ hg add -S foo/bar
26 26 adding foo/bar/z.txt (glob)
27 27 $ hg add -S
28 28 adding x.txt
29 29 adding foo/y.txt (glob)
30 30
31 31 Test recursive status without committing anything:
32 32
33 33 $ hg status -S
34 34 A .hgsub
35 35 A foo/.hgsub
36 36 A foo/bar/z.txt
37 37 A foo/y.txt
38 38 A x.txt
39 39
40 40 Test recursive diff without committing anything:
41 41
42 42 $ hg diff --nodates -S foo
43 43 diff -r 000000000000 foo/.hgsub
44 44 --- /dev/null
45 45 +++ b/foo/.hgsub
46 46 @@ -0,0 +1,1 @@
47 47 +bar = bar
48 48 diff -r 000000000000 foo/y.txt
49 49 --- /dev/null
50 50 +++ b/foo/y.txt
51 51 @@ -0,0 +1,1 @@
52 52 +y1
53 53 diff -r 000000000000 foo/bar/z.txt
54 54 --- /dev/null
55 55 +++ b/foo/bar/z.txt
56 56 @@ -0,0 +1,1 @@
57 57 +z1
58 58
59 59 Commits:
60 60
61 61 $ hg commit -m fails
62 62 abort: uncommitted changes in subrepo foo
63 63 (use --subrepos for recursive commit)
64 64 [255]
65 65
66 66 The --subrepos flag overwrite the config setting:
67 67
68 68 $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos
69 69 committing subrepository foo
70 70 committing subrepository foo/bar (glob)
71 71
72 72 $ cd foo
73 73 $ echo y2 >> y.txt
74 74 $ hg commit -m 0-1-0
75 75
76 76 $ cd bar
77 77 $ echo z2 >> z.txt
78 78 $ hg commit -m 0-1-1
79 79
80 80 $ cd ..
81 81 $ hg commit -m 0-2-1
82 82
83 83 $ cd ..
84 84 $ hg commit -m 1-2-1
85 85
86 86 Change working directory:
87 87
88 88 $ echo y3 >> foo/y.txt
89 89 $ echo z3 >> foo/bar/z.txt
90 90 $ hg status -S
91 91 M foo/bar/z.txt
92 92 M foo/y.txt
93 93 $ hg diff --nodates -S
94 94 diff -r d254738c5f5e foo/y.txt
95 95 --- a/foo/y.txt
96 96 +++ b/foo/y.txt
97 97 @@ -1,2 +1,3 @@
98 98 y1
99 99 y2
100 100 +y3
101 101 diff -r 9647f22de499 foo/bar/z.txt
102 102 --- a/foo/bar/z.txt
103 103 +++ b/foo/bar/z.txt
104 104 @@ -1,2 +1,3 @@
105 105 z1
106 106 z2
107 107 +z3
108 108
109 109 Status call crossing repository boundaries:
110 110
111 111 $ hg status -S foo/bar/z.txt
112 112 M foo/bar/z.txt
113 113 $ hg status -S -I 'foo/?.txt'
114 114 M foo/y.txt
115 115 $ hg status -S -I '**/?.txt'
116 116 M foo/bar/z.txt
117 117 M foo/y.txt
118 118 $ hg diff --nodates -S -I '**/?.txt'
119 119 diff -r d254738c5f5e foo/y.txt
120 120 --- a/foo/y.txt
121 121 +++ b/foo/y.txt
122 122 @@ -1,2 +1,3 @@
123 123 y1
124 124 y2
125 125 +y3
126 126 diff -r 9647f22de499 foo/bar/z.txt
127 127 --- a/foo/bar/z.txt
128 128 +++ b/foo/bar/z.txt
129 129 @@ -1,2 +1,3 @@
130 130 z1
131 131 z2
132 132 +z3
133 133
134 134 Status from within a subdirectory:
135 135
136 136 $ mkdir dir
137 137 $ cd dir
138 138 $ echo a1 > a.txt
139 139 $ hg status -S
140 140 M foo/bar/z.txt
141 141 M foo/y.txt
142 142 ? dir/a.txt
143 143 $ hg diff --nodates -S
144 144 diff -r d254738c5f5e foo/y.txt
145 145 --- a/foo/y.txt
146 146 +++ b/foo/y.txt
147 147 @@ -1,2 +1,3 @@
148 148 y1
149 149 y2
150 150 +y3
151 151 diff -r 9647f22de499 foo/bar/z.txt
152 152 --- a/foo/bar/z.txt
153 153 +++ b/foo/bar/z.txt
154 154 @@ -1,2 +1,3 @@
155 155 z1
156 156 z2
157 157 +z3
158 158
159 159 Status with relative path:
160 160
161 161 $ hg status -S ..
162 162 M ../foo/bar/z.txt
163 163 M ../foo/y.txt
164 164 ? a.txt
165 165
166 166 XXX: filtering lfilesrepo.status() in 3.3-rc causes these files to be listed as
167 167 added instead of modified.
168 168 $ hg status -S .. --config extensions.largefiles=
169 169 M ../foo/bar/z.txt
170 170 M ../foo/y.txt
171 171 ? a.txt
172 172
173 173 $ hg diff --nodates -S ..
174 174 diff -r d254738c5f5e foo/y.txt
175 175 --- a/foo/y.txt
176 176 +++ b/foo/y.txt
177 177 @@ -1,2 +1,3 @@
178 178 y1
179 179 y2
180 180 +y3
181 181 diff -r 9647f22de499 foo/bar/z.txt
182 182 --- a/foo/bar/z.txt
183 183 +++ b/foo/bar/z.txt
184 184 @@ -1,2 +1,3 @@
185 185 z1
186 186 z2
187 187 +z3
188 188 $ cd ..
189 189
190 190 Cleanup and final commit:
191 191
192 192 $ rm -r dir
193 193 $ hg commit --subrepos -m 2-3-2
194 194 committing subrepository foo
195 195 committing subrepository foo/bar (glob)
196 196
197 197 Test explicit path commands within subrepos: add/forget
198 198 $ echo z1 > foo/bar/z2.txt
199 199 $ hg status -S
200 200 ? foo/bar/z2.txt
201 201 $ hg add foo/bar/z2.txt
202 202 $ hg status -S
203 203 A foo/bar/z2.txt
204 204 $ hg forget foo/bar/z2.txt
205 205 $ hg status -S
206 206 ? foo/bar/z2.txt
207 207 $ hg forget foo/bar/z2.txt
208 208 not removing foo/bar/z2.txt: file is already untracked (glob)
209 209 [1]
210 210 $ hg status -S
211 211 ? foo/bar/z2.txt
212 212 $ rm foo/bar/z2.txt
213 213
214 214 Log with the relationships between repo and its subrepo:
215 215
216 216 $ hg log --template '{rev}:{node|short} {desc}\n'
217 217 2:1326fa26d0c0 2-3-2
218 218 1:4b3c9ff4f66b 1-2-1
219 219 0:23376cbba0d8 0-0-0
220 220
221 221 $ hg -R foo log --template '{rev}:{node|short} {desc}\n'
222 222 3:65903cebad86 2-3-2
223 223 2:d254738c5f5e 0-2-1
224 224 1:8629ce7dcc39 0-1-0
225 225 0:af048e97ade2 0-0-0
226 226
227 227 $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n'
228 228 2:31ecbdafd357 2-3-2
229 229 1:9647f22de499 0-1-1
230 230 0:4904098473f9 0-0-0
231 231
232 232 Status between revisions:
233 233
234 234 $ hg status -S
235 235 $ hg status -S --rev 0:1
236 236 M .hgsubstate
237 237 M foo/.hgsubstate
238 238 M foo/bar/z.txt
239 239 M foo/y.txt
240 240 $ hg diff --nodates -S -I '**/?.txt' --rev 0:1
241 241 diff -r af048e97ade2 -r d254738c5f5e foo/y.txt
242 242 --- a/foo/y.txt
243 243 +++ b/foo/y.txt
244 244 @@ -1,1 +1,2 @@
245 245 y1
246 246 +y2
247 247 diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt
248 248 --- a/foo/bar/z.txt
249 249 +++ b/foo/bar/z.txt
250 250 @@ -1,1 +1,2 @@
251 251 z1
252 252 +z2
253 253
254 254 Enable progress extension for archive tests:
255 255
256 256 $ cp $HGRCPATH $HGRCPATH.no-progress
257 257 $ cat >> $HGRCPATH <<EOF
258 258 > [extensions]
259 259 > progress =
260 260 > [progress]
261 261 > assume-tty = 1
262 262 > delay = 0
263 263 > format = topic bar number
264 264 > refresh = 0
265 265 > width = 60
266 266 > EOF
267 267
268 268 Test archiving to a directory tree (the doubled lines in the output
269 269 only show up in the test output, not in real usage):
270 270
271 271 $ hg archive --subrepos ../archive
272 272 \r (no-eol) (esc)
273 273 archiving [ ] 0/3\r (no-eol) (esc)
274 274 archiving [ ] 0/3\r (no-eol) (esc)
275 275 archiving [=============> ] 1/3\r (no-eol) (esc)
276 276 archiving [=============> ] 1/3\r (no-eol) (esc)
277 277 archiving [===========================> ] 2/3\r (no-eol) (esc)
278 278 archiving [===========================> ] 2/3\r (no-eol) (esc)
279 279 archiving [==========================================>] 3/3\r (no-eol) (esc)
280 280 archiving [==========================================>] 3/3\r (no-eol) (esc)
281 281 \r (no-eol) (esc)
282 282 \r (no-eol) (esc)
283 283 archiving (foo) [ ] 0/3\r (no-eol) (esc)
284 284 archiving (foo) [ ] 0/3\r (no-eol) (esc)
285 285 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
286 286 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
287 287 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
288 288 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
289 289 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
290 290 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
291 291 \r (no-eol) (esc)
292 292 \r (no-eol) (esc)
293 293 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
294 294 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
295 295 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
296 296 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
297 297 \r (no-eol) (esc)
298 298 $ find ../archive | sort
299 299 ../archive
300 300 ../archive/.hg_archival.txt
301 301 ../archive/.hgsub
302 302 ../archive/.hgsubstate
303 303 ../archive/foo
304 304 ../archive/foo/.hgsub
305 305 ../archive/foo/.hgsubstate
306 306 ../archive/foo/bar
307 307 ../archive/foo/bar/z.txt
308 308 ../archive/foo/y.txt
309 309 ../archive/x.txt
310 310
311 311 Test archiving to zip file (unzip output is unstable):
312 312
313 313 $ hg archive --subrepos ../archive.zip
314 314 \r (no-eol) (esc)
315 315 archiving [ ] 0/3\r (no-eol) (esc)
316 316 archiving [ ] 0/3\r (no-eol) (esc)
317 317 archiving [=============> ] 1/3\r (no-eol) (esc)
318 318 archiving [=============> ] 1/3\r (no-eol) (esc)
319 319 archiving [===========================> ] 2/3\r (no-eol) (esc)
320 320 archiving [===========================> ] 2/3\r (no-eol) (esc)
321 321 archiving [==========================================>] 3/3\r (no-eol) (esc)
322 322 archiving [==========================================>] 3/3\r (no-eol) (esc)
323 323 \r (no-eol) (esc)
324 324 \r (no-eol) (esc)
325 325 archiving (foo) [ ] 0/3\r (no-eol) (esc)
326 326 archiving (foo) [ ] 0/3\r (no-eol) (esc)
327 327 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
328 328 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
329 329 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
330 330 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
331 331 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
332 332 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
333 333 \r (no-eol) (esc)
334 334 \r (no-eol) (esc)
335 335 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
336 336 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
337 337 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
338 338 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
339 339 \r (no-eol) (esc)
340 340
341 341 Test archiving a revision that references a subrepo that is not yet
342 342 cloned:
343 343
344 344 $ hg clone -U . ../empty
345 \r (no-eol) (esc)
346 linking [ <=> ] 1\r (no-eol) (esc)
347 linking [ <=> ] 2\r (no-eol) (esc)
348 linking [ <=> ] 3\r (no-eol) (esc)
349 linking [ <=> ] 4\r (no-eol) (esc)
350 linking [ <=> ] 5\r (no-eol) (esc)
351 linking [ <=> ] 6\r (no-eol) (esc)
352 linking [ <=> ] 7\r (no-eol) (esc)
353 linking [ <=> ] 8\r (no-eol) (esc)
354 \r (no-eol) (esc)
345 355 $ cd ../empty
346 356 $ hg archive --subrepos -r tip ../archive.tar.gz
347 357 \r (no-eol) (esc)
348 358 archiving [ ] 0/3\r (no-eol) (esc)
349 359 archiving [ ] 0/3\r (no-eol) (esc)
350 360 archiving [=============> ] 1/3\r (no-eol) (esc)
351 361 archiving [=============> ] 1/3\r (no-eol) (esc)
352 362 archiving [===========================> ] 2/3\r (no-eol) (esc)
353 363 archiving [===========================> ] 2/3\r (no-eol) (esc)
354 364 archiving [==========================================>] 3/3\r (no-eol) (esc)
355 365 archiving [==========================================>] 3/3\r (no-eol) (esc)
356 366 \r (no-eol) (esc)
357 367 \r (no-eol) (esc)
368 linking [ <=> ] 1\r (no-eol) (esc)
369 linking [ <=> ] 2\r (no-eol) (esc)
370 linking [ <=> ] 3\r (no-eol) (esc)
371 linking [ <=> ] 4\r (no-eol) (esc)
372 linking [ <=> ] 5\r (no-eol) (esc)
373 linking [ <=> ] 6\r (no-eol) (esc)
374 linking [ <=> ] 7\r (no-eol) (esc)
375 linking [ <=> ] 8\r (no-eol) (esc)
376 \r (no-eol) (esc)
377 \r (no-eol) (esc)
358 378 archiving (foo) [ ] 0/3\r (no-eol) (esc)
359 379 archiving (foo) [ ] 0/3\r (no-eol) (esc)
360 380 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
361 381 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
362 382 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
363 383 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
364 384 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
365 385 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
366 386 \r (no-eol) (esc)
367 387 \r (no-eol) (esc)
388 linking [ <=> ] 1\r (no-eol) (esc)
389 linking [ <=> ] 2\r (no-eol) (esc)
390 linking [ <=> ] 3\r (no-eol) (esc)
391 linking [ <=> ] 4\r (no-eol) (esc)
392 linking [ <=> ] 5\r (no-eol) (esc)
393 linking [ <=> ] 6\r (no-eol) (esc)
394 \r (no-eol) (esc)
395 \r (no-eol) (esc)
368 396 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
369 397 archiving (foo/bar) [ ] 0/1\r (no-eol) (glob) (esc)
370 398 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
371 399 archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc)
372 400 \r (no-eol) (esc)
373 401 cloning subrepo foo from $TESTTMP/repo/foo
374 402 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
375 403
376 404 The newly cloned subrepos contain no working copy:
377 405
378 406 $ hg -R foo summary
379 407 parent: -1:000000000000 (no revision checked out)
380 408 branch: default
381 409 commit: (clean)
382 410 update: 4 new changesets (update)
383 411
384 412 Disable progress extension and cleanup:
385 413
386 414 $ mv $HGRCPATH.no-progress $HGRCPATH
387 415
388 416 Test archiving when there is a directory in the way for a subrepo
389 417 created by archive:
390 418
391 419 $ hg clone -U . ../almost-empty
392 420 $ cd ../almost-empty
393 421 $ mkdir foo
394 422 $ echo f > foo/f
395 423 $ hg archive --subrepos -r tip archive
396 424 cloning subrepo foo from $TESTTMP/empty/foo
397 425 abort: destination '$TESTTMP/almost-empty/foo' is not empty (in subrepo foo) (glob)
398 426 [255]
399 427
400 428 Clone and test outgoing:
401 429
402 430 $ cd ..
403 431 $ hg clone repo repo2
404 432 updating to branch default
405 433 cloning subrepo foo from $TESTTMP/repo/foo
406 434 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
407 435 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 436 $ cd repo2
409 437 $ hg outgoing -S
410 438 comparing with $TESTTMP/repo (glob)
411 439 searching for changes
412 440 no changes found
413 441 comparing with $TESTTMP/repo/foo
414 442 searching for changes
415 443 no changes found
416 444 comparing with $TESTTMP/repo/foo/bar
417 445 searching for changes
418 446 no changes found
419 447 [1]
420 448
421 449 Make nested change:
422 450
423 451 $ echo y4 >> foo/y.txt
424 452 $ hg diff --nodates -S
425 453 diff -r 65903cebad86 foo/y.txt
426 454 --- a/foo/y.txt
427 455 +++ b/foo/y.txt
428 456 @@ -1,3 +1,4 @@
429 457 y1
430 458 y2
431 459 y3
432 460 +y4
433 461 $ hg commit --subrepos -m 3-4-2
434 462 committing subrepository foo
435 463 $ hg outgoing -S
436 464 comparing with $TESTTMP/repo (glob)
437 465 searching for changes
438 466 changeset: 3:2655b8ecc4ee
439 467 tag: tip
440 468 user: test
441 469 date: Thu Jan 01 00:00:00 1970 +0000
442 470 summary: 3-4-2
443 471
444 472 comparing with $TESTTMP/repo/foo
445 473 searching for changes
446 474 changeset: 4:e96193d6cb36
447 475 tag: tip
448 476 user: test
449 477 date: Thu Jan 01 00:00:00 1970 +0000
450 478 summary: 3-4-2
451 479
452 480 comparing with $TESTTMP/repo/foo/bar
453 481 searching for changes
454 482 no changes found
455 483
456 484
457 485 Switch to original repo and setup default path:
458 486
459 487 $ cd ../repo
460 488 $ echo '[paths]' >> .hg/hgrc
461 489 $ echo 'default = ../repo2' >> .hg/hgrc
462 490
463 491 Test incoming:
464 492
465 493 $ hg incoming -S
466 494 comparing with $TESTTMP/repo2 (glob)
467 495 searching for changes
468 496 changeset: 3:2655b8ecc4ee
469 497 tag: tip
470 498 user: test
471 499 date: Thu Jan 01 00:00:00 1970 +0000
472 500 summary: 3-4-2
473 501
474 502 comparing with $TESTTMP/repo2/foo
475 503 searching for changes
476 504 changeset: 4:e96193d6cb36
477 505 tag: tip
478 506 user: test
479 507 date: Thu Jan 01 00:00:00 1970 +0000
480 508 summary: 3-4-2
481 509
482 510 comparing with $TESTTMP/repo2/foo/bar
483 511 searching for changes
484 512 no changes found
485 513
486 514 $ hg incoming -S --bundle incoming.hg
487 515 abort: cannot combine --bundle and --subrepos
488 516 [255]
489 517
490 518 Test missing subrepo:
491 519
492 520 $ rm -r foo
493 521 $ hg status -S
494 522 warning: error "unknown revision '65903cebad86f1a84bd4f1134f62fa7dcb7a1c98'" in subrepository "foo"
495 523
496 524 Issue2619: IndexError: list index out of range on hg add with subrepos
497 525 The subrepo must sorts after the explicit filename.
498 526
499 527 $ cd ..
500 528 $ hg init test
501 529 $ cd test
502 530 $ hg init x
503 531 $ echo "x = x" >> .hgsub
504 532 $ hg add .hgsub
505 533 $ touch a x/a
506 534 $ hg add a x/a
507 535
508 536 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now