mercurial/commands.py
changeset 10350 fd511e9eeea6
parent 10349 20356e69710c
child 10355 a5576908b589
equal deleted inserted replaced
10349:20356e69710c 10350:fd511e9eeea6
  1386         del revfiles[rev]
  1386         del revfiles[rev]
  1387 
  1387 
  1388 def heads(ui, repo, *branchrevs, **opts):
  1388 def heads(ui, repo, *branchrevs, **opts):
  1389     """show current repository heads or show branch heads
  1389     """show current repository heads or show branch heads
  1390 
  1390 
  1391     With no arguments, show all repository head changesets.
  1391     With no arguments, show all repository branch heads.
  1392 
  1392 
  1393     Repository "heads" are changesets with no child changesets. They are
  1393     Repository "heads" are changesets with no child changesets. They are
  1394     where development generally takes place and are the usual targets
  1394     where development generally takes place and are the usual targets
  1395     for update and merge operations.
  1395     for update and merge operations. Branch heads are changesets that have
  1396 
  1396     no child changeset on the same branch.
  1397     If one or more REV is given, the "branch heads" will be shown for
  1397 
  1398     the named branch associated with the specified changeset(s).
  1398     If one or more REVs are given, only branch heads on the branches
  1399 
  1399     associated with the specified changesets are shown.
  1400     Branch heads are changesets on a named branch with no descendants on
       
  1401     the same branch. A branch head could be a "true" (repository) head,
       
  1402     or it could be the last changeset on that branch before it was
       
  1403     merged into another branch, or it could be the last changeset on the
       
  1404     branch before a new branch was created. If none of the branch heads
       
  1405     are true heads, the branch is considered inactive.
       
  1406 
  1400 
  1407     If -c/--closed is specified, also show branch heads marked closed
  1401     If -c/--closed is specified, also show branch heads marked closed
  1408     (see hg commit --close-branch).
  1402     (see hg commit --close-branch).
  1409 
  1403 
  1410     If STARTREV is specified, only those heads that are descendants of
  1404     If STARTREV is specified, only those heads that are descendants of
  1411     STARTREV will be displayed.
  1405     STARTREV will be displayed.
       
  1406 
       
  1407     If -t/--topo is specified, named branch mechanics will be ignored and only
       
  1408     changesets without children will be shown.
  1412     """
  1409     """
  1413 
  1410 
  1414     if opts.get('rev'):
  1411     if opts.get('rev'):
  1415         start = repo.lookup(opts['rev'])
  1412         start = repo.lookup(opts['rev'])
  1416     else:
  1413     else:
  1417         start = None
  1414         start = None
  1418 
  1415 
  1419     closed = opts.get('closed')
  1416     if opts.get('topo'):
  1420     if not branchrevs:
  1417         heads = [repo[h] for h in repo.heads(start)]
  1421         heads = repo.heads(start)
       
  1422 
       
  1423     else:
  1418     else:
  1424 
       
  1425         decode, encode = encoding.fromlocal, encoding.tolocal
       
  1426         heads = []
  1419         heads = []
  1427         branches = set(repo[decode(br)].branch() for br in branchrevs)
       
  1428         for b, ls in repo.branchmap().iteritems():
  1420         for b, ls in repo.branchmap().iteritems():
  1429             if b not in branches:
       
  1430                 continue
       
  1431             if start is None:
  1421             if start is None:
  1432                 heads += ls
  1422                 heads += [repo[h] for h in ls]
  1433                 continue
  1423                 continue
  1434             startrev = repo.changelog.rev(start)
  1424             startrev = repo.changelog.rev(start)
  1435             descendants = set(repo.changelog.descendants(startrev))
  1425             descendants = set(repo.changelog.descendants(startrev))
  1436             descendants.add(startrev)
  1426             descendants.add(startrev)
  1437             heads += [h for h in ls if repo.changelog.rev(h) in descendants]
  1427             rev = repo.changelog.rev
       
  1428             heads += [repo[h] for h in ls if rev(h) in descendants]
       
  1429 
       
  1430     if branchrevs:
       
  1431         decode, encode = encoding.fromlocal, encoding.tolocal
       
  1432         branches = set(repo[decode(br)].branch() for br in branchrevs)
       
  1433         heads = [h for h in heads if h.branch() in branches]
  1438 
  1434 
  1439     if not opts.get('closed'):
  1435     if not opts.get('closed'):
  1440         heads = [h for h in heads if not repo[h].extra().get('close')]
  1436         heads = [h for h in heads if not h.extra().get('close')]
  1441 
  1437 
  1442     if opts.get('active') and branchrevs:
  1438     if opts.get('active') and branchrevs:
  1443         dagheads = repo.heads(start)
  1439         dagheads = repo.heads(start)
  1444         heads = [h for h in heads if h in dagheads]
  1440         heads = [h for h in heads if h.node() in dagheads]
  1445 
  1441 
  1446     if branchrevs:
  1442     if branchrevs:
  1447         haveheads = set(repo[h].branch() for h in heads)
  1443         haveheads = set(h.branch() for h in heads)
  1448         if branches - haveheads:
  1444         if branches - haveheads:
  1449             headless = ', '.join(encode(b) for b in branches - haveheads)
  1445             headless = ', '.join(encode(b) for b in branches - haveheads)
  1450             msg = _('no open branch heads found on branches %s')
  1446             msg = _('no open branch heads found on branches %s')
  1451             if opts.get('rev'):
  1447             if opts.get('rev'):
  1452                 msg += _(' (started at %s)' % opts['rev'])
  1448                 msg += _(' (started at %s)' % opts['rev'])
  1453             ui.warn((msg + '\n') % headless)
  1449             ui.warn((msg + '\n') % headless)
  1454 
  1450 
  1455     if not heads:
  1451     if not heads:
  1456         return 1
  1452         return 1
  1457 
  1453 
  1458     heads = sorted((repo[h] for h in heads), key=lambda x: -x.rev())
  1454     heads = sorted(heads, key=lambda x: -x.rev())
  1459     displayer = cmdutil.show_changeset(ui, repo, opts)
  1455     displayer = cmdutil.show_changeset(ui, repo, opts)
  1460     for ctx in heads:
  1456     for ctx in heads:
  1461         displayer.show(ctx)
  1457         displayer.show(ctx)
  1462     displayer.close()
  1458     displayer.close()
  1463 
  1459 
  3497          ] + walkopts,
  3493          ] + walkopts,
  3498          _('[OPTION]... PATTERN [FILE]...')),
  3494          _('[OPTION]... PATTERN [FILE]...')),
  3499     "heads":
  3495     "heads":
  3500         (heads,
  3496         (heads,
  3501          [('r', 'rev', '', _('show only heads which are descendants of REV')),
  3497          [('r', 'rev', '', _('show only heads which are descendants of REV')),
       
  3498           ('t', 'topo', False, _('show topological heads only')),
  3502           ('a', 'active', False,
  3499           ('a', 'active', False,
  3503            _('show active branchheads only [DEPRECATED]')),
  3500            _('show active branchheads only [DEPRECATED]')),
  3504           ('c', 'closed', False,
  3501           ('c', 'closed', False,
  3505            _('show normal and closed branch heads')),
  3502            _('show normal and closed branch heads')),
  3506          ] + templateopts,
  3503          ] + templateopts,