def advanceboundary(repo, tr, targetphase, nodes, dryrun=None):
    """Add nodes to a phase changing other nodes phases if necessary.

    This function move boundary *forward* this means that all nodes
    are set in the target phase or kept in a *lower* phase.

    Simplify boundary to contains phase roots only.

    If dryrun is True, no actions will be performed

    Returns a set of revs whose phase is changed or should be changed
    """
    phcache = repo._phasecache.copy()
    changes = phcache.advanceboundary(repo, tr, targetphase, nodes, dryrun=
        dryrun)
    if not dryrun:
        repo._phasecache.replace(phcache)
    return changes
