Try to create the PR. If the PR exists, try to find it instead. Raises otherwise.

    You should always use the complete head syntax "org:branch", since the syntax is required
    in case of listing.

    if "none_if_no_commit" is set, return None instead of raising exception if the problem
    is that head and base are the same.

def get_or_create_pull(github_repo, title, body, head, base, *, none_if_no_commit=False):
    """Try to create the PR. If the PR exists, try to find it instead. Raises otherwise.

    You should always use the complete head syntax "org:branch", since the syntax is required
    in case of listing.

    if "none_if_no_commit" is set, return None instead of raising exception if the problem
    is that head and base are the same.
    """
    try: # Try to create or get a PR
        return github_repo.create_pull(
            title=title,
            body=body,
            head=head,
            base=base
        )
    except GithubException as err:
        err_message = err.data['errors'][0].get('message', '')
        if err.status == 422 and err_message.startswith('A pull request already exists'):
            _LOGGER.info('PR already exists, get this PR')
            return list(github_repo.get_pulls(
                head=head,
                base=base
            ))[0]
        elif none_if_no_commit and err.status == 422 and err_message.startswith('No commits between'):
            _LOGGER.info('No PR possible since head %s and base %s are the same',
                         head,
                         base)
            return None
        else:
            _LOGGER.warning("Unable to create PR:\n%s", err.data)
            raise
    except Exception as err:
        response = traceback.format_exc()
        _LOGGER.warning("Unable to create PR:\n%s", response)
        raise