from typing import Tuple


def _is_semantic_diff_kapitan_029_030(win: Tuple[str, str]) -> bool:
    """
    Returns True if a pair of lines of a diff which is already sorted
    by K8s object indicates that this diff contains a semantic change
    when migrating from  Kapitan 0.29 to 0.30.

    The function expects pairs of diff lines as input.

    The function treats the following diffs as non-semantic:
    * Change of "app.kubernetes.io/managed-by: Tiller" to
      "app.kubernetes.io/managed-by: Helm"
    * Change of "heritage: Tiller" to "heritage: Helm"
    * `null` objects not emitted in multi-object YAML documents anymore
    """
    line_a, line_b = map(str.rstrip, win)

    # Ignore context and metadata lines:
    if (
        line_a.startswith(" ")
        or line_b.startswith(" ")
        or line_a.startswith("@@")
        or line_b.startswith("@@")
    ):
        return False

    # Ignore changes where we don't emit a null object preceded or followed
    # by a stream separator anymore
    if line_a == "-null" and line_b in ("----", "---- null"):
        return False
    if line_a == "---- null" and line_b == "----":
        return False

    # Ignore changes which are only about Tiller -> Helm as object manager
    if line_a.startswith("-") and line_b.startswith("+"):
        if line_a.endswith("app.kubernetes.io/managed-by: Tiller") and line_b.endswith(
            "app.kubernetes.io/managed-by: Helm"
        ):
            return False
        if line_a.endswith("heritage: Tiller") and line_b.endswith("heritage: Helm"):
            return False

    # Don't ignore any other diffs
    return True