<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_releasenotes(repo_path, from_commit=None, bugtracker_url=''):
 """ Given a repo and optionally a base revision to start from, will return a text suitable for the relase notes announcement, grouping the bugs, the features and the api-breaking changes. Args: repo_path(str):
 Path to the code git repository. from_commit(str):
 Refspec of the commit to start aggregating the authors from. bugtracker_url(str):
 URL to be prepended to any bug ids found in the commits. Returns: str: Release notes text. """

    repo = dulwich.repo.Repo(repo_path)
    tags = get_tags(repo)
    refs = get_refs(repo)
    maj_version = 0
    feat_version = 0
    fix_version = 0
    start_including = False
    release_notes_per_major = OrderedDict()

    cur_line = ''
    if from_commit is None:
        start_including = True

    prev_version = (maj_version, feat_version, fix_version)
    prev_version_str = '%s.%s.%s' % prev_version
    bugs = []
    features = []
    api_break_changes = []

    for commit_sha, children in reversed(
        get_children_per_first_parent(repo_path).items()
    ):
        commit = get_repo_object(repo, commit_sha)
        maj_version, feat_version, fix_version = get_version(
            commit=commit,
            tags=tags,
            maj_version=maj_version,
            feat_version=feat_version,
            fix_version=fix_version,
            children=children,
        )
        version = (maj_version, feat_version, fix_version)
        version_str = '%s.%s.%s' % version

        if (
            start_including or commit_sha.startswith(from_commit) or
            fuzzy_matches_refs(from_commit, refs.get(commit_sha, []))
        ):
            start_including = True

            parent_commit_type = get_commit_type(
                commit=commit,
                children=children,
                tags=tags,
                prev_version=prev_version,
            )
            cur_line = pretty_commit(
                commit=commit,
                version=version_str,
                bugtracker_url=bugtracker_url,
                commit_type=parent_commit_type,
            )
            for child in children:
                commit_type = get_commit_type(
                    commit=commit,
                    tags=tags,
                    prev_version=prev_version,
                )
                cur_line += pretty_commit(
                    commit=child,
                    version=None,
                    commit_type=commit_type,
                    bugtracker_url=bugtracker_url,
                )

            if parent_commit_type == 'api_break':
                release_notes_per_major[prev_version_str] = (
                    api_break_changes,
                    features,
                    bugs,
                )
                bugs, features, api_break_changes = [], [], []
                api_break_changes.append(cur_line)
            elif parent_commit_type == 'feature':
                features.append(cur_line)
            else:
                bugs.append(cur_line)

        prev_version = version
        prev_version_str = version_str

    release_notes_per_major[prev_version_str] = (
        api_break_changes,
        features,
        bugs,
    )

    releasenotes = ''
    for major_version, lines in reversed(release_notes_per_major.items()):
        api_break_changes, features, bugs = lines
        releasenotes += u'''New changes for version %s
=================================

API Breaking changes
--------------------
%s
New features
------------
%s
Bugfixes and minor changes
--------------------------
%s

''' % (
                major_version,
                (
                    '\n'.join(reversed(api_break_changes)) or
                    'No new API breaking changes\n'
                ),
                '\n'.join(reversed(features)) or 'No new features\n',
                '\n'.join(reversed(bugs)) or 'No new bugs\n',
            )

    return releasenotes.strip()