##// END OF EJS Templates
share: backout fd903f89e42b, except the test...
Matt Harbison -
r18511:798ab869 stable
parent child Browse files
Show More
@@ -1,635 +1,632
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, url
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 openpath(ui, path):
93 93 '''open path with open if local, url.open if remote'''
94 94 if islocal(path):
95 95 return util.posixfile(util.urllocalpath(path), 'rb')
96 96 else:
97 97 return url.open(ui, path)
98 98
99 99 def _peerorrepo(ui, path, create=False):
100 100 """return a repository object for the specified path"""
101 101 obj = _peerlookup(path).instance(ui, path, create)
102 102 ui = getattr(obj, "ui", ui)
103 103 for name, module in extensions.extensions():
104 104 hook = getattr(module, 'reposetup', None)
105 105 if hook:
106 106 hook(ui, obj)
107 107 return obj
108 108
109 109 def repository(ui, path='', create=False):
110 110 """return a repository object for the specified path"""
111 111 peer = _peerorrepo(ui, path, create)
112 112 repo = peer.local()
113 113 if not repo:
114 114 raise util.Abort(_("repository '%s' is not local") %
115 115 (path or peer.url()))
116 116 return repo.filtered('visible')
117 117
118 118 def peer(uiorrepo, opts, path, create=False):
119 119 '''return a repository peer for the specified path'''
120 120 rui = remoteui(uiorrepo, opts)
121 121 return _peerorrepo(rui, path, create).peer()
122 122
123 123 def defaultdest(source):
124 124 '''return default destination of clone if none is given'''
125 125 return os.path.basename(os.path.normpath(util.url(source).path))
126 126
127 127 def share(ui, source, dest=None, update=True):
128 128 '''create a shared repository'''
129 129
130 130 if not islocal(source):
131 131 raise util.Abort(_('can only share local repositories'))
132 132
133 133 if not dest:
134 134 dest = defaultdest(source)
135 135 else:
136 136 dest = ui.expandpath(dest)
137 137
138 138 if isinstance(source, str):
139 139 origsource = ui.expandpath(source)
140 140 source, branches = parseurl(origsource)
141 141 srcrepo = repository(ui, source)
142 142 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
143 143 else:
144 144 srcrepo = source.local()
145 145 origsource = source = srcrepo.url()
146 146 checkout = None
147 147
148 148 sharedpath = srcrepo.sharedpath # if our source is already sharing
149 149
150 150 root = os.path.realpath(dest)
151 151 roothg = os.path.join(root, '.hg')
152 152
153 153 if os.path.exists(roothg):
154 154 raise util.Abort(_('destination already exists'))
155 155
156 156 if not os.path.isdir(root):
157 157 os.mkdir(root)
158 158 util.makedir(roothg, notindexed=True)
159 159
160 160 requirements = ''
161 161 try:
162 162 requirements = srcrepo.opener.read('requires')
163 163 except IOError, inst:
164 164 if inst.errno != errno.ENOENT:
165 165 raise
166 166
167 167 requirements += 'shared\n'
168 168 util.writefile(os.path.join(roothg, 'requires'), requirements)
169 169 util.writefile(os.path.join(roothg, 'sharedpath'), sharedpath)
170 170
171 171 r = repository(ui, root)
172 172
173 173 default = srcrepo.ui.config('paths', 'default')
174 if not default:
175 # set default to source for being able to clone subrepos
176 default = os.path.abspath(util.urllocalpath(origsource))
174 if default:
177 175 fp = r.opener("hgrc", "w", text=True)
178 176 fp.write("[paths]\n")
179 177 fp.write("default = %s\n" % default)
180 178 fp.close()
181 r.ui.setconfig('paths', 'default', default)
182 179
183 180 if update:
184 181 r.ui.status(_("updating working directory\n"))
185 182 if update is not True:
186 183 checkout = update
187 184 for test in (checkout, 'default', 'tip'):
188 185 if test is None:
189 186 continue
190 187 try:
191 188 uprev = r.lookup(test)
192 189 break
193 190 except error.RepoLookupError:
194 191 continue
195 192 _update(r, uprev)
196 193
197 194 def copystore(ui, srcrepo, destpath):
198 195 '''copy files from store of srcrepo in destpath
199 196
200 197 returns destlock
201 198 '''
202 199 destlock = None
203 200 try:
204 201 hardlink = None
205 202 num = 0
206 203 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
207 204 for f in srcrepo.store.copylist():
208 205 if srcpublishing and f.endswith('phaseroots'):
209 206 continue
210 207 src = os.path.join(srcrepo.sharedpath, f)
211 208 dst = os.path.join(destpath, f)
212 209 dstbase = os.path.dirname(dst)
213 210 if dstbase and not os.path.exists(dstbase):
214 211 os.mkdir(dstbase)
215 212 if os.path.exists(src):
216 213 if dst.endswith('data'):
217 214 # lock to avoid premature writing to the target
218 215 destlock = lock.lock(os.path.join(dstbase, "lock"))
219 216 hardlink, n = util.copyfiles(src, dst, hardlink)
220 217 num += n
221 218 if hardlink:
222 219 ui.debug("linked %d files\n" % num)
223 220 else:
224 221 ui.debug("copied %d files\n" % num)
225 222 return destlock
226 223 except: # re-raises
227 224 release(destlock)
228 225 raise
229 226
230 227 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
231 228 update=True, stream=False, branch=None):
232 229 """Make a copy of an existing repository.
233 230
234 231 Create a copy of an existing repository in a new directory. The
235 232 source and destination are URLs, as passed to the repository
236 233 function. Returns a pair of repository peers, the source and
237 234 newly created destination.
238 235
239 236 The location of the source is added to the new repository's
240 237 .hg/hgrc file, as the default to be used for future pulls and
241 238 pushes.
242 239
243 240 If an exception is raised, the partly cloned/updated destination
244 241 repository will be deleted.
245 242
246 243 Arguments:
247 244
248 245 source: repository object or URL
249 246
250 247 dest: URL of destination repository to create (defaults to base
251 248 name of source repository)
252 249
253 250 pull: always pull from source repository, even in local case
254 251
255 252 stream: stream raw data uncompressed from repository (fast over
256 253 LAN, slow over WAN)
257 254
258 255 rev: revision to clone up to (implies pull=True)
259 256
260 257 update: update working directory after clone completes, if
261 258 destination is local repository (True means update to default rev,
262 259 anything else is treated as a revision)
263 260
264 261 branch: branches to clone
265 262 """
266 263
267 264 if isinstance(source, str):
268 265 origsource = ui.expandpath(source)
269 266 source, branch = parseurl(origsource, branch)
270 267 srcpeer = peer(ui, peeropts, source)
271 268 else:
272 269 srcpeer = source.peer() # in case we were called with a localrepo
273 270 branch = (None, branch or [])
274 271 origsource = source = srcpeer.url()
275 272 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
276 273
277 274 if dest is None:
278 275 dest = defaultdest(source)
279 276 ui.status(_("destination directory: %s\n") % dest)
280 277 else:
281 278 dest = ui.expandpath(dest)
282 279
283 280 dest = util.urllocalpath(dest)
284 281 source = util.urllocalpath(source)
285 282
286 283 if not dest:
287 284 raise util.Abort(_("empty destination path is not valid"))
288 285 if os.path.exists(dest):
289 286 if not os.path.isdir(dest):
290 287 raise util.Abort(_("destination '%s' already exists") % dest)
291 288 elif os.listdir(dest):
292 289 raise util.Abort(_("destination '%s' is not empty") % dest)
293 290
294 291 srclock = destlock = cleandir = None
295 292 srcrepo = srcpeer.local()
296 293 try:
297 294 abspath = origsource
298 295 if islocal(origsource):
299 296 abspath = os.path.abspath(util.urllocalpath(origsource))
300 297
301 298 if islocal(dest):
302 299 cleandir = dest
303 300
304 301 copy = False
305 302 if (srcrepo and srcrepo.cancopy() and islocal(dest)
306 303 and not phases.hassecret(srcrepo)):
307 304 copy = not pull and not rev
308 305
309 306 if copy:
310 307 try:
311 308 # we use a lock here because if we race with commit, we
312 309 # can end up with extra data in the cloned revlogs that's
313 310 # not pointed to by changesets, thus causing verify to
314 311 # fail
315 312 srclock = srcrepo.lock(wait=False)
316 313 except error.LockError:
317 314 copy = False
318 315
319 316 if copy:
320 317 srcrepo.hook('preoutgoing', throw=True, source='clone')
321 318 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
322 319 if not os.path.exists(dest):
323 320 os.mkdir(dest)
324 321 else:
325 322 # only clean up directories we create ourselves
326 323 cleandir = hgdir
327 324 try:
328 325 destpath = hgdir
329 326 util.makedir(destpath, notindexed=True)
330 327 except OSError, inst:
331 328 if inst.errno == errno.EEXIST:
332 329 cleandir = None
333 330 raise util.Abort(_("destination '%s' already exists")
334 331 % dest)
335 332 raise
336 333
337 334 destlock = copystore(ui, srcrepo, destpath)
338 335
339 336 # Recomputing branch cache might be slow on big repos,
340 337 # so just copy it
341 338 dstcachedir = os.path.join(destpath, 'cache')
342 339 srcbranchcache = srcrepo.sjoin('cache/branchheads')
343 340 dstbranchcache = os.path.join(dstcachedir, 'branchheads')
344 341 if os.path.exists(srcbranchcache):
345 342 if not os.path.exists(dstcachedir):
346 343 os.mkdir(dstcachedir)
347 344 util.copyfile(srcbranchcache, dstbranchcache)
348 345
349 346 # we need to re-init the repo after manually copying the data
350 347 # into it
351 348 destpeer = peer(srcrepo, peeropts, dest)
352 349 srcrepo.hook('outgoing', source='clone',
353 350 node=node.hex(node.nullid))
354 351 else:
355 352 try:
356 353 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
357 354 # only pass ui when no srcrepo
358 355 except OSError, inst:
359 356 if inst.errno == errno.EEXIST:
360 357 cleandir = None
361 358 raise util.Abort(_("destination '%s' already exists")
362 359 % dest)
363 360 raise
364 361
365 362 revs = None
366 363 if rev:
367 364 if not srcpeer.capable('lookup'):
368 365 raise util.Abort(_("src repository does not support "
369 366 "revision lookup and so doesn't "
370 367 "support clone by revision"))
371 368 revs = [srcpeer.lookup(r) for r in rev]
372 369 checkout = revs[0]
373 370 if destpeer.local():
374 371 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
375 372 elif srcrepo:
376 373 srcrepo.push(destpeer, revs=revs)
377 374 else:
378 375 raise util.Abort(_("clone from remote to remote not supported"))
379 376
380 377 cleandir = None
381 378
382 379 # clone all bookmarks except divergent ones
383 380 destrepo = destpeer.local()
384 381 if destrepo and srcpeer.capable("pushkey"):
385 382 rb = srcpeer.listkeys('bookmarks')
386 383 marks = destrepo._bookmarks
387 384 for k, n in rb.iteritems():
388 385 try:
389 386 m = destrepo.lookup(n)
390 387 marks[k] = m
391 388 except error.RepoLookupError:
392 389 pass
393 390 if rb:
394 391 marks.write()
395 392 elif srcrepo and destpeer.capable("pushkey"):
396 393 for k, n in srcrepo._bookmarks.iteritems():
397 394 destpeer.pushkey('bookmarks', k, '', hex(n))
398 395
399 396 if destrepo:
400 397 fp = destrepo.opener("hgrc", "w", text=True)
401 398 fp.write("[paths]\n")
402 399 u = util.url(abspath)
403 400 u.passwd = None
404 401 defaulturl = str(u)
405 402 fp.write("default = %s\n" % defaulturl)
406 403 fp.close()
407 404
408 405 destrepo.ui.setconfig('paths', 'default', defaulturl)
409 406
410 407 if update:
411 408 if update is not True:
412 409 checkout = srcpeer.lookup(update)
413 410 uprev = None
414 411 status = None
415 412 if checkout is not None:
416 413 try:
417 414 uprev = destrepo.lookup(checkout)
418 415 except error.RepoLookupError:
419 416 pass
420 417 if uprev is None:
421 418 try:
422 419 uprev = destrepo._bookmarks['@']
423 420 update = '@'
424 421 bn = destrepo[uprev].branch()
425 422 if bn == 'default':
426 423 status = _("updating to bookmark @\n")
427 424 else:
428 425 status = _("updating to bookmark @ on branch %s\n"
429 426 % bn)
430 427 except KeyError:
431 428 try:
432 429 uprev = destrepo.branchtip('default')
433 430 except error.RepoLookupError:
434 431 uprev = destrepo.lookup('tip')
435 432 if not status:
436 433 bn = destrepo[uprev].branch()
437 434 status = _("updating to branch %s\n") % bn
438 435 destrepo.ui.status(status)
439 436 _update(destrepo, uprev)
440 437 if update in destrepo._bookmarks:
441 438 bookmarks.setcurrent(destrepo, update)
442 439
443 440 return srcpeer, destpeer
444 441 finally:
445 442 release(srclock, destlock)
446 443 if cleandir is not None:
447 444 shutil.rmtree(cleandir, True)
448 445 if srcpeer is not None:
449 446 srcpeer.close()
450 447
451 448 def _showstats(repo, stats):
452 449 repo.ui.status(_("%d files updated, %d files merged, "
453 450 "%d files removed, %d files unresolved\n") % stats)
454 451
455 452 def updaterepo(repo, node, overwrite):
456 453 """Update the working directory to node.
457 454
458 455 When overwrite is set, changes are clobbered, merged else
459 456
460 457 returns stats (see pydoc mercurial.merge.applyupdates)"""
461 458 return mergemod.update(repo, node, False, overwrite, None)
462 459
463 460 def update(repo, node):
464 461 """update the working directory to node, merging linear changes"""
465 462 stats = updaterepo(repo, node, False)
466 463 _showstats(repo, stats)
467 464 if stats[3]:
468 465 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
469 466 return stats[3] > 0
470 467
471 468 # naming conflict in clone()
472 469 _update = update
473 470
474 471 def clean(repo, node, show_stats=True):
475 472 """forcibly switch the working directory to node, clobbering changes"""
476 473 stats = updaterepo(repo, node, True)
477 474 if show_stats:
478 475 _showstats(repo, stats)
479 476 return stats[3] > 0
480 477
481 478 def merge(repo, node, force=None, remind=True):
482 479 """Branch merge with node, resolving changes. Return true if any
483 480 unresolved conflicts."""
484 481 stats = mergemod.update(repo, node, True, force, False)
485 482 _showstats(repo, stats)
486 483 if stats[3]:
487 484 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
488 485 "or 'hg update -C .' to abandon\n"))
489 486 elif remind:
490 487 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
491 488 return stats[3] > 0
492 489
493 490 def _incoming(displaychlist, subreporecurse, ui, repo, source,
494 491 opts, buffered=False):
495 492 """
496 493 Helper for incoming / gincoming.
497 494 displaychlist gets called with
498 495 (remoterepo, incomingchangesetlist, displayer) parameters,
499 496 and is supposed to contain only code that can't be unified.
500 497 """
501 498 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
502 499 other = peer(repo, opts, source)
503 500 ui.status(_('comparing with %s\n') % util.hidepassword(source))
504 501 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
505 502
506 503 if revs:
507 504 revs = [other.lookup(rev) for rev in revs]
508 505 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
509 506 revs, opts["bundle"], opts["force"])
510 507 try:
511 508 if not chlist:
512 509 ui.status(_("no changes found\n"))
513 510 return subreporecurse()
514 511
515 512 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
516 513
517 514 # XXX once graphlog extension makes it into core,
518 515 # should be replaced by a if graph/else
519 516 displaychlist(other, chlist, displayer)
520 517
521 518 displayer.close()
522 519 finally:
523 520 cleanupfn()
524 521 subreporecurse()
525 522 return 0 # exit code is zero since we found incoming changes
526 523
527 524 def incoming(ui, repo, source, opts):
528 525 def subreporecurse():
529 526 ret = 1
530 527 if opts.get('subrepos'):
531 528 ctx = repo[None]
532 529 for subpath in sorted(ctx.substate):
533 530 sub = ctx.sub(subpath)
534 531 ret = min(ret, sub.incoming(ui, source, opts))
535 532 return ret
536 533
537 534 def display(other, chlist, displayer):
538 535 limit = cmdutil.loglimit(opts)
539 536 if opts.get('newest_first'):
540 537 chlist.reverse()
541 538 count = 0
542 539 for n in chlist:
543 540 if limit is not None and count >= limit:
544 541 break
545 542 parents = [p for p in other.changelog.parents(n) if p != nullid]
546 543 if opts.get('no_merges') and len(parents) == 2:
547 544 continue
548 545 count += 1
549 546 displayer.show(other[n])
550 547 return _incoming(display, subreporecurse, ui, repo, source, opts)
551 548
552 549 def _outgoing(ui, repo, dest, opts):
553 550 dest = ui.expandpath(dest or 'default-push', dest or 'default')
554 551 dest, branches = parseurl(dest, opts.get('branch'))
555 552 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
556 553 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
557 554 if revs:
558 555 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
559 556
560 557 other = peer(repo, opts, dest)
561 558 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
562 559 force=opts.get('force'))
563 560 o = outgoing.missing
564 561 if not o:
565 562 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
566 563 return None
567 564 return o
568 565
569 566 def outgoing(ui, repo, dest, opts):
570 567 def recurse():
571 568 ret = 1
572 569 if opts.get('subrepos'):
573 570 ctx = repo[None]
574 571 for subpath in sorted(ctx.substate):
575 572 sub = ctx.sub(subpath)
576 573 ret = min(ret, sub.outgoing(ui, dest, opts))
577 574 return ret
578 575
579 576 limit = cmdutil.loglimit(opts)
580 577 o = _outgoing(ui, repo, dest, opts)
581 578 if o is None:
582 579 return recurse()
583 580
584 581 if opts.get('newest_first'):
585 582 o.reverse()
586 583 displayer = cmdutil.show_changeset(ui, repo, opts)
587 584 count = 0
588 585 for n in o:
589 586 if limit is not None and count >= limit:
590 587 break
591 588 parents = [p for p in repo.changelog.parents(n) if p != nullid]
592 589 if opts.get('no_merges') and len(parents) == 2:
593 590 continue
594 591 count += 1
595 592 displayer.show(repo[n])
596 593 displayer.close()
597 594 recurse()
598 595 return 0 # exit code is zero since we found outgoing changes
599 596
600 597 def revert(repo, node, choose):
601 598 """revert changes to revision in node without updating dirstate"""
602 599 return mergemod.update(repo, node, False, True, choose)[3] > 0
603 600
604 601 def verify(repo):
605 602 """verify the consistency of a repository"""
606 603 return verifymod.verify(repo)
607 604
608 605 def remoteui(src, opts):
609 606 'build a remote ui from ui or repo and opts'
610 607 if util.safehasattr(src, 'baseui'): # looks like a repository
611 608 dst = src.baseui.copy() # drop repo-specific config
612 609 src = src.ui # copy target options from repo
613 610 else: # assume it's a global ui object
614 611 dst = src.copy() # keep all global options
615 612
616 613 # copy ssh-specific options
617 614 for o in 'ssh', 'remotecmd':
618 615 v = opts.get(o) or src.config('ui', o)
619 616 if v:
620 617 dst.setconfig("ui", o, v)
621 618
622 619 # copy bundle-specific options
623 620 r = src.config('bundle', 'mainreporoot')
624 621 if r:
625 622 dst.setconfig('bundle', 'mainreporoot', r)
626 623
627 624 # copy selected local settings to the remote ui
628 625 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
629 626 for key, val in src.configitems(sect):
630 627 dst.setconfig(sect, key, val)
631 628 v = src.config('web', 'cacerts')
632 629 if v:
633 630 dst.setconfig('web', 'cacerts', util.expandpath(v))
634 631
635 632 return dst
@@ -1,1066 +1,1064
1 1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2 2
3 3 $ echo "[ui]" >> $HGRCPATH
4 4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5 5
6 6 $ hg init t
7 7 $ cd t
8 8
9 9 first revision, no sub
10 10
11 11 $ echo a > a
12 12 $ hg ci -Am0
13 13 adding a
14 14
15 15 add first sub
16 16
17 17 $ echo s = s > .hgsub
18 18 $ hg add .hgsub
19 19 $ hg init s
20 20 $ echo a > s/a
21 21
22 22 Issue2232: committing a subrepo without .hgsub
23 23
24 24 $ hg ci -mbad s
25 25 abort: can't commit subrepos without .hgsub
26 26 [255]
27 27
28 28 $ hg -R s ci -Ams0
29 29 adding a
30 30 $ hg sum
31 31 parent: 0:f7b1eb17ad24 tip
32 32 0
33 33 branch: default
34 34 commit: 1 added, 1 subrepos
35 35 update: (current)
36 36 $ hg ci -m1
37 37
38 38 Revert subrepo and test subrepo fileset keyword:
39 39
40 40 $ echo b > s/a
41 41 $ hg revert "set:subrepo('glob:s*')"
42 42 reverting subrepo s
43 43 reverting s/a (glob)
44 44 $ rm s/a.orig
45 45
46 46 Revert subrepo with no backup. The "reverting s/a" line is gone since
47 47 we're really running 'hg update' in the subrepo:
48 48
49 49 $ echo b > s/a
50 50 $ hg revert --no-backup s
51 51 reverting subrepo s
52 52
53 53 Issue2022: update -C
54 54
55 55 $ echo b > s/a
56 56 $ hg sum
57 57 parent: 1:7cf8cfea66e4 tip
58 58 1
59 59 branch: default
60 60 commit: 1 subrepos
61 61 update: (current)
62 62 $ hg co -C 1
63 63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 64 $ hg sum
65 65 parent: 1:7cf8cfea66e4 tip
66 66 1
67 67 branch: default
68 68 commit: (clean)
69 69 update: (current)
70 70
71 71 commands that require a clean repo should respect subrepos
72 72
73 73 $ echo b >> s/a
74 74 $ hg backout tip
75 75 abort: uncommitted changes in subrepo s
76 76 [255]
77 77 $ hg revert -C -R s s/a
78 78
79 79 add sub sub
80 80
81 81 $ echo ss = ss > s/.hgsub
82 82 $ hg init s/ss
83 83 $ echo a > s/ss/a
84 84 $ hg -R s add s/.hgsub
85 85 $ hg -R s/ss add s/ss/a
86 86 $ hg sum
87 87 parent: 1:7cf8cfea66e4 tip
88 88 1
89 89 branch: default
90 90 commit: 1 subrepos
91 91 update: (current)
92 92 $ hg ci -m2
93 93 committing subrepository s
94 94 committing subrepository s/ss (glob)
95 95 $ hg sum
96 96 parent: 2:df30734270ae tip
97 97 2
98 98 branch: default
99 99 commit: (clean)
100 100 update: (current)
101 101
102 102 bump sub rev (and check it is ignored by ui.commitsubrepos)
103 103
104 104 $ echo b > s/a
105 105 $ hg -R s ci -ms1
106 106 $ hg --config ui.commitsubrepos=no ci -m3
107 107
108 108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
109 109
110 110 $ echo c > s/a
111 111 $ hg --config ui.commitsubrepos=no ci -m4
112 112 abort: uncommitted changes in subrepo s
113 113 (use --subrepos for recursive commit)
114 114 [255]
115 115 $ hg id
116 116 f6affe3fbfaa+ tip
117 117 $ hg -R s ci -mc
118 118 $ hg id
119 119 f6affe3fbfaa+ tip
120 120 $ echo d > s/a
121 121 $ hg ci -m4
122 122 committing subrepository s
123 123 $ hg tip -R s
124 124 changeset: 4:02dcf1d70411
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: 4
129 129
130 130
131 131 check caching
132 132
133 133 $ hg co 0
134 134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
135 135 $ hg debugsub
136 136
137 137 restore
138 138
139 139 $ hg co
140 140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 141 $ hg debugsub
142 142 path s
143 143 source s
144 144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
145 145
146 146 new branch for merge tests
147 147
148 148 $ hg co 1
149 149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 150 $ echo t = t >> .hgsub
151 151 $ hg init t
152 152 $ echo t > t/t
153 153 $ hg -R t add t
154 154 adding t/t (glob)
155 155
156 156 5
157 157
158 158 $ hg ci -m5 # add sub
159 159 committing subrepository t
160 160 created new head
161 161 $ echo t2 > t/t
162 162
163 163 6
164 164
165 165 $ hg st -R s
166 166 $ hg ci -m6 # change sub
167 167 committing subrepository t
168 168 $ hg debugsub
169 169 path s
170 170 source s
171 171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
172 172 path t
173 173 source t
174 174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
175 175 $ echo t3 > t/t
176 176
177 177 7
178 178
179 179 $ hg ci -m7 # change sub again for conflict test
180 180 committing subrepository t
181 181 $ hg rm .hgsub
182 182
183 183 8
184 184
185 185 $ hg ci -m8 # remove sub
186 186
187 187 merge tests
188 188
189 189 $ hg co -C 3
190 190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 191 $ hg merge 5 # test adding
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 (branch merge, don't forget to commit)
194 194 $ hg debugsub
195 195 path s
196 196 source s
197 197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
198 198 path t
199 199 source t
200 200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
201 201 $ hg ci -m9
202 202 created new head
203 203 $ hg merge 6 --debug # test change
204 204 searching for copies back to rev 2
205 205 resolving manifests
206 206 overwrite: False, partial: False
207 207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
208 208 .hgsubstate: versions differ -> m
209 209 updating: .hgsubstate 1/1 files (100.00%)
210 210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
211 211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
212 212 getting subrepo t
213 213 searching for copies back to rev 1
214 214 resolving manifests
215 215 overwrite: False, partial: False
216 216 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
217 217 t: remote is newer -> g
218 218 updating: t 1/1 files (100.00%)
219 219 getting t
220 220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 221 (branch merge, don't forget to commit)
222 222 $ hg debugsub
223 223 path s
224 224 source s
225 225 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
226 226 path t
227 227 source t
228 228 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
229 229 $ echo conflict > t/t
230 230 $ hg ci -m10
231 231 committing subrepository t
232 232 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
233 233 searching for copies back to rev 2
234 234 resolving manifests
235 235 overwrite: False, partial: False
236 236 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
237 237 .hgsubstate: versions differ -> m
238 238 updating: .hgsubstate 1/1 files (100.00%)
239 239 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
240 240 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
241 241 merging subrepo t
242 242 searching for copies back to rev 2
243 243 resolving manifests
244 244 overwrite: False, partial: False
245 245 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
246 246 t: versions differ -> m
247 247 preserving t for resolve of t
248 248 updating: t 1/1 files (100.00%)
249 249 picked tool 'internal:merge' for t (binary False symlink False)
250 250 merging t
251 251 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
252 252 warning: conflicts during merge.
253 253 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
254 254 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
255 255 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
256 256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 257 (branch merge, don't forget to commit)
258 258
259 259 should conflict
260 260
261 261 $ cat t/t
262 262 <<<<<<< local
263 263 conflict
264 264 =======
265 265 t3
266 266 >>>>>>> other
267 267
268 268 clone
269 269
270 270 $ cd ..
271 271 $ hg clone t tc
272 272 updating to branch default
273 273 cloning subrepo s from $TESTTMP/t/s (glob)
274 274 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
275 275 cloning subrepo t from $TESTTMP/t/t (glob)
276 276 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 277 $ cd tc
278 278 $ hg debugsub
279 279 path s
280 280 source s
281 281 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
282 282 path t
283 283 source t
284 284 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
285 285
286 286 push
287 287
288 288 $ echo bah > t/t
289 289 $ hg ci -m11
290 290 committing subrepository t
291 291 $ hg push
292 292 pushing to $TESTTMP/t (glob)
293 293 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
294 294 searching for changes
295 295 no changes found
296 296 pushing subrepo s to $TESTTMP/t/s (glob)
297 297 searching for changes
298 298 no changes found
299 299 pushing subrepo t to $TESTTMP/t/t (glob)
300 300 searching for changes
301 301 adding changesets
302 302 adding manifests
303 303 adding file changes
304 304 added 1 changesets with 1 changes to 1 files
305 305 searching for changes
306 306 adding changesets
307 307 adding manifests
308 308 adding file changes
309 309 added 1 changesets with 1 changes to 1 files
310 310
311 311 push -f
312 312
313 313 $ echo bah > s/a
314 314 $ hg ci -m12
315 315 committing subrepository s
316 316 $ hg push
317 317 pushing to $TESTTMP/t (glob)
318 318 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
319 319 searching for changes
320 320 no changes found
321 321 pushing subrepo s to $TESTTMP/t/s (glob)
322 322 searching for changes
323 323 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
324 324 (did you forget to merge? use push -f to force)
325 325 [255]
326 326 $ hg push -f
327 327 pushing to $TESTTMP/t (glob)
328 328 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
329 329 searching for changes
330 330 no changes found
331 331 pushing subrepo s to $TESTTMP/t/s (glob)
332 332 searching for changes
333 333 adding changesets
334 334 adding manifests
335 335 adding file changes
336 336 added 1 changesets with 1 changes to 1 files (+1 heads)
337 337 pushing subrepo t to $TESTTMP/t/t (glob)
338 338 searching for changes
339 339 no changes found
340 340 searching for changes
341 341 adding changesets
342 342 adding manifests
343 343 adding file changes
344 344 added 1 changesets with 1 changes to 1 files
345 345
346 346 update
347 347
348 348 $ cd ../t
349 349 $ hg up -C # discard our earlier merge
350 350 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 351 $ echo blah > t/t
352 352 $ hg ci -m13
353 353 committing subrepository t
354 354
355 355 pull
356 356
357 357 $ cd ../tc
358 358 $ hg pull
359 359 pulling from $TESTTMP/t (glob)
360 360 searching for changes
361 361 adding changesets
362 362 adding manifests
363 363 adding file changes
364 364 added 1 changesets with 1 changes to 1 files
365 365 (run 'hg update' to get a working copy)
366 366
367 367 should pull t
368 368
369 369 $ hg up
370 370 pulling subrepo t from $TESTTMP/t/t (glob)
371 371 searching for changes
372 372 adding changesets
373 373 adding manifests
374 374 adding file changes
375 375 added 1 changesets with 1 changes to 1 files
376 376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 377 $ cat t/t
378 378 blah
379 379
380 380 bogus subrepo path aborts
381 381
382 382 $ echo 'bogus=[boguspath' >> .hgsub
383 383 $ hg ci -m 'bogus subrepo path'
384 384 abort: missing ] in subrepo source
385 385 [255]
386 386
387 387 Issue1986: merge aborts when trying to merge a subrepo that
388 388 shouldn't need merging
389 389
390 390 # subrepo layout
391 391 #
392 392 # o 5 br
393 393 # /|
394 394 # o | 4 default
395 395 # | |
396 396 # | o 3 br
397 397 # |/|
398 398 # o | 2 default
399 399 # | |
400 400 # | o 1 br
401 401 # |/
402 402 # o 0 default
403 403
404 404 $ cd ..
405 405 $ rm -rf sub
406 406 $ hg init main
407 407 $ cd main
408 408 $ hg init s
409 409 $ cd s
410 410 $ echo a > a
411 411 $ hg ci -Am1
412 412 adding a
413 413 $ hg branch br
414 414 marked working directory as branch br
415 415 (branches are permanent and global, did you want a bookmark?)
416 416 $ echo a >> a
417 417 $ hg ci -m1
418 418 $ hg up default
419 419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 420 $ echo b > b
421 421 $ hg ci -Am1
422 422 adding b
423 423 $ hg up br
424 424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
425 425 $ hg merge tip
426 426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 427 (branch merge, don't forget to commit)
428 428 $ hg ci -m1
429 429 $ hg up 2
430 430 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 431 $ echo c > c
432 432 $ hg ci -Am1
433 433 adding c
434 434 $ hg up 3
435 435 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
436 436 $ hg merge 4
437 437 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 438 (branch merge, don't forget to commit)
439 439 $ hg ci -m1
440 440
441 441 # main repo layout:
442 442 #
443 443 # * <-- try to merge default into br again
444 444 # .`|
445 445 # . o 5 br --> substate = 5
446 446 # . |
447 447 # o | 4 default --> substate = 4
448 448 # | |
449 449 # | o 3 br --> substate = 2
450 450 # |/|
451 451 # o | 2 default --> substate = 2
452 452 # | |
453 453 # | o 1 br --> substate = 3
454 454 # |/
455 455 # o 0 default --> substate = 2
456 456
457 457 $ cd ..
458 458 $ echo 's = s' > .hgsub
459 459 $ hg -R s up 2
460 460 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
461 461 $ hg ci -Am1
462 462 adding .hgsub
463 463 $ hg branch br
464 464 marked working directory as branch br
465 465 (branches are permanent and global, did you want a bookmark?)
466 466 $ echo b > b
467 467 $ hg -R s up 3
468 468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 469 $ hg ci -Am1
470 470 adding b
471 471 $ hg up default
472 472 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
473 473 $ echo c > c
474 474 $ hg ci -Am1
475 475 adding c
476 476 $ hg up 1
477 477 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 478 $ hg merge 2
479 479 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 480 (branch merge, don't forget to commit)
481 481 $ hg ci -m1
482 482 $ hg up 2
483 483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 484 $ hg -R s up 4
485 485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 486 $ echo d > d
487 487 $ hg ci -Am1
488 488 adding d
489 489 $ hg up 3
490 490 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
491 491 $ hg -R s up 5
492 492 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
493 493 $ echo e > e
494 494 $ hg ci -Am1
495 495 adding e
496 496
497 497 $ hg up 5
498 498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 499 $ hg merge 4 # try to merge default into br again
500 500 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 501 (branch merge, don't forget to commit)
502 502 $ cd ..
503 503
504 504 test subrepo delete from .hgsubstate
505 505
506 506 $ hg init testdelete
507 507 $ mkdir testdelete/nested testdelete/nested2
508 508 $ hg init testdelete/nested
509 509 $ hg init testdelete/nested2
510 510 $ echo test > testdelete/nested/foo
511 511 $ echo test > testdelete/nested2/foo
512 512 $ hg -R testdelete/nested add
513 513 adding testdelete/nested/foo (glob)
514 514 $ hg -R testdelete/nested2 add
515 515 adding testdelete/nested2/foo (glob)
516 516 $ hg -R testdelete/nested ci -m test
517 517 $ hg -R testdelete/nested2 ci -m test
518 518 $ echo nested = nested > testdelete/.hgsub
519 519 $ echo nested2 = nested2 >> testdelete/.hgsub
520 520 $ hg -R testdelete add
521 521 adding testdelete/.hgsub (glob)
522 522 $ hg -R testdelete ci -m "nested 1 & 2 added"
523 523 $ echo nested = nested > testdelete/.hgsub
524 524 $ hg -R testdelete ci -m "nested 2 deleted"
525 525 $ cat testdelete/.hgsubstate
526 526 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
527 527 $ hg -R testdelete remove testdelete/.hgsub
528 528 $ hg -R testdelete ci -m ".hgsub deleted"
529 529 $ cat testdelete/.hgsubstate
530 530 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
531 531
532 532 test repository cloning
533 533
534 534 $ mkdir mercurial mercurial2
535 535 $ hg init nested_absolute
536 536 $ echo test > nested_absolute/foo
537 537 $ hg -R nested_absolute add
538 538 adding nested_absolute/foo (glob)
539 539 $ hg -R nested_absolute ci -mtest
540 540 $ cd mercurial
541 541 $ hg init nested_relative
542 542 $ echo test2 > nested_relative/foo2
543 543 $ hg -R nested_relative add
544 544 adding nested_relative/foo2 (glob)
545 545 $ hg -R nested_relative ci -mtest2
546 546 $ hg init main
547 547 $ echo "nested_relative = ../nested_relative" > main/.hgsub
548 548 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
549 549 $ hg -R main add
550 550 adding main/.hgsub (glob)
551 551 $ hg -R main ci -m "add subrepos"
552 552 $ cd ..
553 553 $ hg clone mercurial/main mercurial2/main
554 554 updating to branch default
555 555 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 556 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
557 557 > mercurial2/main/nested_relative/.hg/hgrc
558 558 [paths]
559 559 default = $TESTTMP/mercurial/nested_absolute
560 560 [paths]
561 561 default = $TESTTMP/mercurial/nested_relative
562 562 $ rm -rf mercurial mercurial2
563 563
564 564 Issue1977: multirepo push should fail if subrepo push fails
565 565
566 566 $ hg init repo
567 567 $ hg init repo/s
568 568 $ echo a > repo/s/a
569 569 $ hg -R repo/s ci -Am0
570 570 adding a
571 571 $ echo s = s > repo/.hgsub
572 572 $ hg -R repo ci -Am1
573 573 adding .hgsub
574 574 $ hg clone repo repo2
575 575 updating to branch default
576 576 cloning subrepo s from $TESTTMP/repo/s (glob)
577 577 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 578 $ hg -q -R repo2 pull -u
579 579 $ echo 1 > repo2/s/a
580 580 $ hg -R repo2/s ci -m2
581 581 $ hg -q -R repo2/s push
582 582 $ hg -R repo2/s up -C 0
583 583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 584 $ echo 2 > repo2/s/b
585 585 $ hg -R repo2/s ci -m3 -A
586 586 adding b
587 587 created new head
588 588 $ hg -R repo2 ci -m3
589 589 $ hg -q -R repo2 push
590 590 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
591 591 (did you forget to merge? use push -f to force)
592 592 [255]
593 593 $ hg -R repo update
594 594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 595
596 596 test if untracked file is not overwritten
597 597
598 598 $ echo issue3276_ok > repo/s/b
599 599 $ hg -R repo2 push -f -q
600 600 $ hg -R repo update
601 601 b: untracked file differs
602 602 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
603 603 [255]
604 604
605 605 $ cat repo/s/b
606 606 issue3276_ok
607 607 $ rm repo/s/b
608 608 $ hg -R repo revert --all
609 609 reverting repo/.hgsubstate (glob)
610 610 reverting subrepo s
611 611 $ hg -R repo update
612 612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 613 $ cat repo/s/b
614 614 2
615 615 $ rm -rf repo2 repo
616 616
617 617
618 618 Issue1852 subrepos with relative paths always push/pull relative to default
619 619
620 620 Prepare a repo with subrepo
621 621
622 622 $ hg init issue1852a
623 623 $ cd issue1852a
624 624 $ hg init sub/repo
625 625 $ echo test > sub/repo/foo
626 626 $ hg -R sub/repo add sub/repo/foo
627 627 $ echo sub/repo = sub/repo > .hgsub
628 628 $ hg add .hgsub
629 629 $ hg ci -mtest
630 630 committing subrepository sub/repo (glob)
631 631 $ echo test >> sub/repo/foo
632 632 $ hg ci -mtest
633 633 committing subrepository sub/repo (glob)
634 634 $ cd ..
635 635
636 636 Create repo without default path, pull top repo, and see what happens on update
637 637
638 638 $ hg init issue1852b
639 639 $ hg -R issue1852b pull issue1852a
640 640 pulling from issue1852a
641 641 requesting all changes
642 642 adding changesets
643 643 adding manifests
644 644 adding file changes
645 645 added 2 changesets with 3 changes to 2 files
646 646 (run 'hg update' to get a working copy)
647 647 $ hg -R issue1852b update
648 648 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
649 649 [255]
650 650
651 651 Pull -u now doesn't help
652 652
653 653 $ hg -R issue1852b pull -u issue1852a
654 654 pulling from issue1852a
655 655 searching for changes
656 656 no changes found
657 657
658 658 Try the same, but with pull -u
659 659
660 660 $ hg init issue1852c
661 661 $ hg -R issue1852c pull -r0 -u issue1852a
662 662 pulling from issue1852a
663 663 adding changesets
664 664 adding manifests
665 665 adding file changes
666 666 added 1 changesets with 2 changes to 2 files
667 667 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
668 668 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
669 669
670 670 Try to push from the other side
671 671
672 672 $ hg -R issue1852a push `pwd`/issue1852c
673 673 pushing to $TESTTMP/issue1852c
674 674 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
675 675 searching for changes
676 676 no changes found
677 677 searching for changes
678 678 adding changesets
679 679 adding manifests
680 680 adding file changes
681 681 added 1 changesets with 1 changes to 1 files
682 682
683 683 Incoming and outgoing should not use the default path:
684 684
685 685 $ hg clone -q issue1852a issue1852d
686 686 $ hg -R issue1852d outgoing --subrepos issue1852c
687 687 comparing with issue1852c
688 688 searching for changes
689 689 no changes found
690 690 comparing with issue1852c/sub/repo
691 691 searching for changes
692 692 no changes found
693 693 [1]
694 694 $ hg -R issue1852d incoming --subrepos issue1852c
695 695 comparing with issue1852c
696 696 searching for changes
697 697 no changes found
698 698 comparing with issue1852c/sub/repo
699 699 searching for changes
700 700 no changes found
701 701 [1]
702 702
703 703 Check status of files when none of them belong to the first
704 704 subrepository:
705 705
706 706 $ hg init subrepo-status
707 707 $ cd subrepo-status
708 708 $ hg init subrepo-1
709 709 $ hg init subrepo-2
710 710 $ cd subrepo-2
711 711 $ touch file
712 712 $ hg add file
713 713 $ cd ..
714 714 $ echo subrepo-1 = subrepo-1 > .hgsub
715 715 $ echo subrepo-2 = subrepo-2 >> .hgsub
716 716 $ hg add .hgsub
717 717 $ hg ci -m 'Added subrepos'
718 718 committing subrepository subrepo-2
719 719 $ hg st subrepo-2/file
720 720
721 721 Check that share works with subrepo
722 722 $ hg --config extensions.share= share . ../shared
723 723 updating working directory
724 724 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
725 725 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 726 $ test -f ../shared/subrepo-1/.hg/sharedpath
727 727 [1]
728 728 $ hg -R ../shared in
729 comparing with $TESTTMP/subrepo-status (glob)
730 searching for changes
731 no changes found
732 [1]
729 abort: repository default not found!
730 [255]
733 731 $ hg -R ../shared/subrepo-2 showconfig paths
734 732 paths.default=$TESTTMP/subrepo-status/subrepo-2
735 733 $ hg -R ../shared/subrepo-1 sum --remote
736 734 parent: -1:000000000000 tip (empty repository)
737 735 branch: default
738 736 commit: (clean)
739 737 update: (current)
740 738 remote: (synced)
741 739
742 740 Check hg update --clean
743 741 $ cd $TESTTMP/t
744 742 $ rm -r t/t.orig
745 743 $ hg status -S --all
746 744 C .hgsub
747 745 C .hgsubstate
748 746 C a
749 747 C s/.hgsub
750 748 C s/.hgsubstate
751 749 C s/a
752 750 C s/ss/a
753 751 C t/t
754 752 $ echo c1 > s/a
755 753 $ cd s
756 754 $ echo c1 > b
757 755 $ echo c1 > c
758 756 $ hg add b
759 757 $ cd ..
760 758 $ hg status -S
761 759 M s/a
762 760 A s/b
763 761 ? s/c
764 762 $ hg update -C
765 763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
766 764 $ hg status -S
767 765 ? s/b
768 766 ? s/c
769 767
770 768 Sticky subrepositories, no changes
771 769 $ cd $TESTTMP/t
772 770 $ hg id
773 771 925c17564ef8 tip
774 772 $ hg -R s id
775 773 12a213df6fa9 tip
776 774 $ hg -R t id
777 775 52c0adc0515a tip
778 776 $ hg update 11
779 777 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
780 778 $ hg id
781 779 365661e5936a
782 780 $ hg -R s id
783 781 fc627a69481f
784 782 $ hg -R t id
785 783 e95bcfa18a35
786 784
787 785 Sticky subrepositorys, file changes
788 786 $ touch s/f1
789 787 $ touch t/f1
790 788 $ hg add -S s/f1
791 789 $ hg add -S t/f1
792 790 $ hg id
793 791 365661e5936a+
794 792 $ hg -R s id
795 793 fc627a69481f+
796 794 $ hg -R t id
797 795 e95bcfa18a35+
798 796 $ hg update tip
799 797 subrepository sources for s differ
800 798 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
801 799 l
802 800 subrepository sources for t differ
803 801 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
804 802 l
805 803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
806 804 $ hg id
807 805 925c17564ef8+ tip
808 806 $ hg -R s id
809 807 fc627a69481f+
810 808 $ hg -R t id
811 809 e95bcfa18a35+
812 810 $ hg update --clean tip
813 811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
814 812
815 813 Sticky subrepository, revision updates
816 814 $ hg id
817 815 925c17564ef8 tip
818 816 $ hg -R s id
819 817 12a213df6fa9 tip
820 818 $ hg -R t id
821 819 52c0adc0515a tip
822 820 $ cd s
823 821 $ hg update -r -2
824 822 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
825 823 $ cd ../t
826 824 $ hg update -r 2
827 825 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
828 826 $ cd ..
829 827 $ hg update 10
830 828 subrepository sources for t differ (in checked out version)
831 829 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
832 830 l
833 831 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
834 832 $ hg id
835 833 e45c8b14af55+
836 834 $ hg -R s id
837 835 02dcf1d70411
838 836 $ hg -R t id
839 837 7af322bc1198
840 838
841 839 Sticky subrepository, file changes and revision updates
842 840 $ touch s/f1
843 841 $ touch t/f1
844 842 $ hg add -S s/f1
845 843 $ hg add -S t/f1
846 844 $ hg id
847 845 e45c8b14af55+
848 846 $ hg -R s id
849 847 02dcf1d70411+
850 848 $ hg -R t id
851 849 7af322bc1198+
852 850 $ hg update tip
853 851 subrepository sources for s differ
854 852 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
855 853 l
856 854 subrepository sources for t differ
857 855 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
858 856 l
859 857 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
860 858 $ hg id
861 859 925c17564ef8+ tip
862 860 $ hg -R s id
863 861 02dcf1d70411+
864 862 $ hg -R t id
865 863 7af322bc1198+
866 864
867 865 Sticky repository, update --clean
868 866 $ hg update --clean tip
869 867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
870 868 $ hg id
871 869 925c17564ef8 tip
872 870 $ hg -R s id
873 871 12a213df6fa9 tip
874 872 $ hg -R t id
875 873 52c0adc0515a tip
876 874
877 875 Test subrepo already at intended revision:
878 876 $ cd s
879 877 $ hg update fc627a69481f
880 878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 879 $ cd ..
882 880 $ hg update 11
883 881 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
884 882 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
885 883 $ hg id -n
886 884 11+
887 885 $ hg -R s id
888 886 fc627a69481f
889 887 $ hg -R t id
890 888 e95bcfa18a35
891 889
892 890 Test that removing .hgsubstate doesn't break anything:
893 891
894 892 $ hg rm -f .hgsubstate
895 893 $ hg ci -mrm
896 894 nothing changed
897 895 [1]
898 896 $ hg log -vr tip
899 897 changeset: 13:925c17564ef8
900 898 tag: tip
901 899 user: test
902 900 date: Thu Jan 01 00:00:00 1970 +0000
903 901 files: .hgsubstate
904 902 description:
905 903 13
906 904
907 905
908 906
909 907 Test that removing .hgsub removes .hgsubstate:
910 908
911 909 $ hg rm .hgsub
912 910 $ hg ci -mrm2
913 911 created new head
914 912 $ hg log -vr tip
915 913 changeset: 14:2400bccd50af
916 914 tag: tip
917 915 parent: 11:365661e5936a
918 916 user: test
919 917 date: Thu Jan 01 00:00:00 1970 +0000
920 918 files: .hgsub .hgsubstate
921 919 description:
922 920 rm2
923 921
924 922
925 923 Test issue3153: diff -S with deleted subrepos
926 924
927 925 $ hg diff --nodates -S -c .
928 926 diff -r 365661e5936a -r 2400bccd50af .hgsub
929 927 --- a/.hgsub
930 928 +++ /dev/null
931 929 @@ -1,2 +0,0 @@
932 930 -s = s
933 931 -t = t
934 932 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
935 933 --- a/.hgsubstate
936 934 +++ /dev/null
937 935 @@ -1,2 +0,0 @@
938 936 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
939 937 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
940 938
941 939 Test behavior of add for explicit path in subrepo:
942 940 $ cd ..
943 941 $ hg init explicit
944 942 $ cd explicit
945 943 $ echo s = s > .hgsub
946 944 $ hg add .hgsub
947 945 $ hg init s
948 946 $ hg ci -m0
949 947 Adding with an explicit path in a subrepo adds the file
950 948 $ echo c1 > f1
951 949 $ echo c2 > s/f2
952 950 $ hg st -S
953 951 ? f1
954 952 ? s/f2
955 953 $ hg add s/f2
956 954 $ hg st -S
957 955 A s/f2
958 956 ? f1
959 957 $ hg ci -R s -m0
960 958 $ hg ci -Am1
961 959 adding f1
962 960 Adding with an explicit path in a subrepo with -S has the same behavior
963 961 $ echo c3 > f3
964 962 $ echo c4 > s/f4
965 963 $ hg st -S
966 964 ? f3
967 965 ? s/f4
968 966 $ hg add -S s/f4
969 967 $ hg st -S
970 968 A s/f4
971 969 ? f3
972 970 $ hg ci -R s -m1
973 971 $ hg ci -Ama2
974 972 adding f3
975 973 Adding without a path or pattern silently ignores subrepos
976 974 $ echo c5 > f5
977 975 $ echo c6 > s/f6
978 976 $ echo c7 > s/f7
979 977 $ hg st -S
980 978 ? f5
981 979 ? s/f6
982 980 ? s/f7
983 981 $ hg add
984 982 adding f5
985 983 $ hg st -S
986 984 A f5
987 985 ? s/f6
988 986 ? s/f7
989 987 $ hg ci -R s -Am2
990 988 adding f6
991 989 adding f7
992 990 $ hg ci -m3
993 991 Adding without a path or pattern with -S also adds files in subrepos
994 992 $ echo c8 > f8
995 993 $ echo c9 > s/f9
996 994 $ echo c10 > s/f10
997 995 $ hg st -S
998 996 ? f8
999 997 ? s/f10
1000 998 ? s/f9
1001 999 $ hg add -S
1002 1000 adding f8
1003 1001 adding s/f10 (glob)
1004 1002 adding s/f9 (glob)
1005 1003 $ hg st -S
1006 1004 A f8
1007 1005 A s/f10
1008 1006 A s/f9
1009 1007 $ hg ci -R s -m3
1010 1008 $ hg ci -m4
1011 1009 Adding with a pattern silently ignores subrepos
1012 1010 $ echo c11 > fm11
1013 1011 $ echo c12 > fn12
1014 1012 $ echo c13 > s/fm13
1015 1013 $ echo c14 > s/fn14
1016 1014 $ hg st -S
1017 1015 ? fm11
1018 1016 ? fn12
1019 1017 ? s/fm13
1020 1018 ? s/fn14
1021 1019 $ hg add 'glob:**fm*'
1022 1020 adding fm11
1023 1021 $ hg st -S
1024 1022 A fm11
1025 1023 ? fn12
1026 1024 ? s/fm13
1027 1025 ? s/fn14
1028 1026 $ hg ci -R s -Am4
1029 1027 adding fm13
1030 1028 adding fn14
1031 1029 $ hg ci -Am5
1032 1030 adding fn12
1033 1031 Adding with a pattern with -S also adds matches in subrepos
1034 1032 $ echo c15 > fm15
1035 1033 $ echo c16 > fn16
1036 1034 $ echo c17 > s/fm17
1037 1035 $ echo c18 > s/fn18
1038 1036 $ hg st -S
1039 1037 ? fm15
1040 1038 ? fn16
1041 1039 ? s/fm17
1042 1040 ? s/fn18
1043 1041 $ hg add -S 'glob:**fm*'
1044 1042 adding fm15
1045 1043 adding s/fm17 (glob)
1046 1044 $ hg st -S
1047 1045 A fm15
1048 1046 A s/fm17
1049 1047 ? fn16
1050 1048 ? s/fn18
1051 1049 $ hg ci -R s -Am5
1052 1050 adding fn18
1053 1051 $ hg ci -Am6
1054 1052 adding fn16
1055 1053
1056 1054 Test behavior of forget for explicit path in subrepo:
1057 1055 Forgetting an explicit path in a subrepo untracks the file
1058 1056 $ echo c19 > s/f19
1059 1057 $ hg add s/f19
1060 1058 $ hg st -S
1061 1059 A s/f19
1062 1060 $ hg forget s/f19
1063 1061 $ hg st -S
1064 1062 ? s/f19
1065 1063 $ rm s/f19
1066 1064 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now