def METHOD_NAME(lhs_project: Optional[Project], rhs_project: Optional[Project]) -> Set[int]:
    """Resolve the direct lineage path from lhs_project node to rhs_project node in a projects hierarchy tree
    Given a projects hierarchy
                 A
                / \
               B   C
                 / | \
                D  E  F
                     / \
                    G   H
    The lineage path from D to G
                   C
                 /   \
                D     F
                     /
                    G
    With C as the common ancestor, the ancestor lineage above C is omitted as it is unnecessary
    get_direct_lineage_hierarchy_ids(D, G) -> [D.id, C.id, F.id, G.id]
    If any projects of the function arguments are empty, the function will resolve the lineage
    path of the non-empty project up to the root project
    The lineage path from D to None
                 A
                  \
                   C
                 /
                D
    get_direct_lineage_hierarchy_ids(D, None) -> [D.id, C.id, A.id]
    If both projects are not in the same hierarchy, the function will return empty set
    """
    lhs_lineage = get_project_lineage_ids(lhs_project) if lhs_project else []
    rhs_lineage = get_project_lineage_ids(rhs_project) if rhs_project else []
    # Only hierarchy up to the nearest common ancestor are needed to link between the project and the new parent.
    # Don't include project to find common ancestor to prevent the possibility that new parent is child of project.
    common_ancestor = get_first_common_item(lhs_lineage, rhs_lineage)
    if not common_ancestor:
        return set()
    # Remove all projects that are ancestors of the nearest common ancestor and make the nearest common ancestor
    # as the root of the hierarchy.
    return set(lhs_lineage).symmetric_difference(set(rhs_lineage)) | {common_ancestor}