Remove elements from root and head where ``source`` matches the update.

    This is useful if the update needs to overwrite all elements with the same
    source.

    .. note::
        If the update doesn't contain exactly one source in ``field``, the
        records are returned with no modifications.

    Args:
        field (str): the field to filter out.
        root (pmap): the root record, whose ``field`` will be cleaned.
        head (pmap): the head record, whose ``field`` will be cleaned.
        update (pmap): the update record, from which the ``source`` is read.

    Returns:
        tuple: ``(root, head, update)`` with some elements filtered out from
            ``root`` and ``head``.

def keep_only_update_source_in_field(field, root, head, update):
    """Remove elements from root and head where ``source`` matches the update.

    This is useful if the update needs to overwrite all elements with the same
    source.

    .. note::
        If the update doesn't contain exactly one source in ``field``, the
        records are returned with no modifications.

    Args:
        field (str): the field to filter out.
        root (pmap): the root record, whose ``field`` will be cleaned.
        head (pmap): the head record, whose ``field`` will be cleaned.
        update (pmap): the update record, from which the ``source`` is read.

    Returns:
        tuple: ``(root, head, update)`` with some elements filtered out from
            ``root`` and ``head``.
    """
    update_sources = {source.lower() for source in get_value(thaw(update), '.'.join([field, 'source']), [])}
    if len(update_sources) != 1:
        return root, head, update
    source = update_sources.pop()

    if field in root:
        root = root.set(field, remove_elements_with_source(source, root[field]))
    if field in head:
        head = head.set(field, remove_elements_with_source(source, head[field]))

    return root, head, update