comparison mercurial/hg.py @ 46931:d4e4ccb75f99

outgoing: accept multiple destinations This align the behavior of `hg outgoing` with the one of `hg incoming`. In addition this prepare the introduction of having simple `path` resolve to multiple destination in practice (eg: `default`) Differential Revision: https://phab.mercurial-scm.org/D10391
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 14 Apr 2021 01:26:44 +0200
parents 0afe96e374a7
children dec31caf5fd6
comparison
equal deleted inserted replaced
46930:0afe96e374a7 46931:d4e4ccb75f99
1318 displayer.show(other[n]) 1318 displayer.show(other[n])
1319 1319
1320 return _incoming(display, subreporecurse, ui, repo, source, opts) 1320 return _incoming(display, subreporecurse, ui, repo, source, opts)
1321 1321
1322 1322
1323 def _outgoing(ui, repo, dest, opts, subpath=None): 1323 def _outgoing(ui, repo, dests, opts, subpath=None):
1324 path = ui.getpath(dest, default=(b'default-push', b'default')) 1324 out = set()
1325 if not path: 1325 others = []
1326 raise error.Abort( 1326 for path in urlutil.get_push_paths(repo, ui, dests):
1327 _(b'default repository not configured!'), 1327 dest = path.pushloc or path.loc
1328 hint=_(b"see 'hg help config.paths'"), 1328 if subpath is not None:
1329 ) 1329 subpath = urlutil.url(subpath)
1330 dest = path.pushloc or path.loc 1330 if subpath.isabs():
1331 if subpath is not None: 1331 dest = bytes(subpath)
1332 subpath = urlutil.url(subpath) 1332 else:
1333 if subpath.isabs(): 1333 p = urlutil.url(dest)
1334 dest = bytes(subpath) 1334 p.path = os.path.normpath(b'%s/%s' % (p.path, subpath))
1335 else: 1335 dest = bytes(p)
1336 p = urlutil.url(dest) 1336 branches = path.branch, opts.get(b'branch') or []
1337 p.path = os.path.normpath(b'%s/%s' % (p.path, subpath)) 1337
1338 dest = bytes(p) 1338 ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(dest))
1339 1339 revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev'))
1340 branches = path.branch, opts.get(b'branch') or [] 1340 if revs:
1341 1341 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
1342 ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(dest)) 1342
1343 revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev')) 1343 other = peer(repo, opts, dest)
1344 if revs: 1344 try:
1345 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)] 1345 outgoing = discovery.findcommonoutgoing(
1346 1346 repo, other, revs, force=opts.get(b'force')
1347 other = peer(repo, opts, dest) 1347 )
1348 try: 1348 o = outgoing.missing
1349 outgoing = discovery.findcommonoutgoing( 1349 out.update(o)
1350 repo, other, revs, force=opts.get(b'force') 1350 if not o:
1351 ) 1351 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
1352 o = outgoing.missing 1352 others.append(other)
1353 if not o: 1353 except: # re-raises
1354 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded) 1354 other.close()
1355 return o, other 1355 raise
1356 except: # re-raises 1356 # make sure this is ordered by revision number
1357 other.close() 1357 outgoing_revs = list(out)
1358 raise 1358 cl = repo.changelog
1359 1359 outgoing_revs.sort(key=cl.rev)
1360 1360 return outgoing_revs, others
1361 def _outgoing_recurse(ui, repo, dest, opts): 1361
1362
1363 def _outgoing_recurse(ui, repo, dests, opts):
1362 ret = 1 1364 ret = 1
1363 if opts.get(b'subrepos'): 1365 if opts.get(b'subrepos'):
1364 ctx = repo[None] 1366 ctx = repo[None]
1365 for subpath in sorted(ctx.substate): 1367 for subpath in sorted(ctx.substate):
1366 sub = ctx.sub(subpath) 1368 sub = ctx.sub(subpath)
1367 ret = min(ret, sub.outgoing(ui, dest, opts)) 1369 ret = min(ret, sub.outgoing(ui, dests, opts))
1368 return ret 1370 return ret
1369 1371
1370 1372
1371 def _outgoing_filter(repo, revs, opts): 1373 def _outgoing_filter(repo, revs, opts):
1372 """apply revision filtering/ordering option for outgoing""" 1374 """apply revision filtering/ordering option for outgoing"""
1389 continue 1391 continue
1390 count += 1 1392 count += 1
1391 yield n 1393 yield n
1392 1394
1393 1395
1394 def outgoing(ui, repo, dest, opts, subpath=None): 1396 def outgoing(ui, repo, dests, opts, subpath=None):
1395 if opts.get(b'graph'): 1397 if opts.get(b'graph'):
1396 logcmdutil.checkunsupportedgraphflags([], opts) 1398 logcmdutil.checkunsupportedgraphflags([], opts)
1397 o, other = _outgoing(ui, repo, dest, opts, subpath=subpath) 1399 o, others = _outgoing(ui, repo, dests, opts, subpath=subpath)
1398 ret = 1 1400 ret = 1
1399 try: 1401 try:
1400 if o: 1402 if o:
1401 ret = 0 1403 ret = 0
1402 1404
1413 ui.pager(b'outgoing') 1415 ui.pager(b'outgoing')
1414 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) 1416 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
1415 for n in _outgoing_filter(repo, o, opts): 1417 for n in _outgoing_filter(repo, o, opts):
1416 displayer.show(repo[n]) 1418 displayer.show(repo[n])
1417 displayer.close() 1419 displayer.close()
1418 cmdutil.outgoinghooks(ui, repo, other, opts, o) 1420 for oth in others:
1419 ret = min(ret, _outgoing_recurse(ui, repo, dest, opts)) 1421 cmdutil.outgoinghooks(ui, repo, oth, opts, o)
1422 ret = min(ret, _outgoing_recurse(ui, repo, dests, opts))
1420 return ret # exit code is zero since we found outgoing changes 1423 return ret # exit code is zero since we found outgoing changes
1421 finally: 1424 finally:
1422 other.close() 1425 for oth in others:
1426 oth.close()
1423 1427
1424 1428
1425 def verify(repo, level=None): 1429 def verify(repo, level=None):
1426 """verify the consistency of a repository""" 1430 """verify the consistency of a repository"""
1427 ret = verifymod.verify(repo, level=level) 1431 ret = verifymod.verify(repo, level=level)