# Buggy code
def api_github_v2(
    user_profile,
    event,
    payload,
    branches,
    default_stream,
    commit_stream,
    issue_stream,
    topic_focus=None,
):
    # type: (UserProfile, Text, Mapping[Text, Any], Text, Text, Text, Text, Optional[Text]) -> Tuple[Text, Text, Text]
    """
    processes github payload with version 2 field specification
    `payload` comes in unmodified from github
    `default_stream` is set to what `stream` is in v1 above
    `commit_stream` and `issue_stream` fall back to `default_stream` if they are empty
    This and allowing alternative endpoints is what distinguishes v1 from v2 of the github configuration
    """
    target_stream = commit_stream if commit_stream else default_stream
    issue_stream = issue_stream if issue_stream else default_stream
    repository = payload["repository"]
    topic_focus = topic_focus if topic_focus else repository["name"]

    # Event Handlers
    if event == "pull_request":
        subject = get_pull_request_or_issue_subject(
            repository, payload["pull_request"], "PR"
        )
        content = github_pull_request_content(payload)
    elif event == "issues":
        # in v1, we assume that this stream exists since it is
        # deprecated and the few realms that use it already have the
        # stream
        target_stream = issue_stream
        subject = get_pull_request_or_issue_subject(
            repository, payload["issue"], "Issue"
        )
        content = github_issues_content(payload)
    elif event == "issue_comment":
        # Comments on both issues and pull requests come in as issue_comment events
        issue = payload["issue"]
        if "pull_request" not in issue or issue["pull_request"]["diff_url"] is None:
            # It's an issues comment
            target_stream = issue_stream
            type = "Issue"
            subject = get_pull_request_or_issue_subject(
                repository, payload["issue"], type
            )
        else:
            # It's a pull request comment
            type = "PR"
            subject = get_pull_request_or_issue_subject(
                repository, payload["issue"], type
            )

        content = github_object_commented_content(payload, type)

    elif event == "push":
        subject, content = build_message_from_gitlog(
            user_profile,
            topic_focus,
            payload["ref"],
            payload["commits"],
            payload["before"],
            payload["after"],
            payload["compare"],
            payload["pusher"]["name"],
            forced=payload["forced"],
            created=payload["created"],
        )
    elif event == "commit_comment":
        subject = topic_focus

        comment = payload.get("comment")
        action = "[commented]({})".format(comment["html_url"])
        content = get_commits_comment_action_message(
            comment["user"]["login"],
            action,
            comment["html_url"].split("#", 1)[0],
            comment["commit_id"],
            comment["body"],
        )

    else:
        raise UnknownEventType(
            force_str("Event %s is unknown and cannot be handled" % (event,))
        )

    return target_stream, subject, content


# Traceback (IndexError)
Traceback (most recent call last):
File "/home/zulip/deployments/2017-05-10-06-16-16/zulip-venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/zulip/deployments/2017-05-10-06-16-16/zulip-venv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "./zerver/webhooks/github_dispatcher.py", line 15, in api_github_webhook_dispatch
return api_github_landing(request)
File "/home/zulip/deployments/2017-05-10-06-16-16/zulip-venv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "./zerver/decorator.py", line 104, in wrapper
return func(request, *args, **kwargs)
File "./zerver/lib/request.py", line 166, in _wrapped_view_func
return view_func(request, *args, **kwargs)
File "./zerver/decorator.py", line 384, in _wrapped_func_arguments
return limited_func(request, user_profile, *args, **kwargs)
File "./zerver/decorator.py", line 664, in wrapped_func
return func(request, *args, **kwargs)
File "./zerver/lib/request.py", line 166, in _wrapped_view_func
return view_func(request, *args, **kwargs)
File "./zerver/webhooks/github/view.py", line 270, in api_github_landing
**kwargs)
File "./zerver/webhooks/github/view.py", line 175, in api_github_v2
created=payload['created'])
File "./zerver/webhooks/github/view.py", line 294, in build_message_from_gitlog
content = get_push_commits_event_message(pusher, url, short_ref, commits)
File "./zerver/lib/webhooks/git.py", line 64, in get_push_commits_event_message
committers_details = "{} ({})".format(*committers_items[0])
IndexError: list index out of range

# Fixed code
def api_github_v2(
    user_profile,
    event,
    payload,
    branches,
    default_stream,
    commit_stream,
    issue_stream,
    topic_focus=None,
):
    # type: (UserProfile, Text, Mapping[Text, Any], Text, Text, Text, Text, Optional[Text]) -> Tuple[Text, Text, Text]
    """
    processes github payload with version 2 field specification
    `payload` comes in unmodified from github
    `default_stream` is set to what `stream` is in v1 above
    `commit_stream` and `issue_stream` fall back to `default_stream` if they are empty
    This and allowing alternative endpoints is what distinguishes v1 from v2 of the github configuration
    """
    target_stream = commit_stream if commit_stream else default_stream
    issue_stream = issue_stream if issue_stream else default_stream
    repository = payload["repository"]
    topic_focus = topic_focus if topic_focus else repository["name"]

    # Event Handlers
    if event == "pull_request":
        subject = get_pull_request_or_issue_subject(
            repository, payload["pull_request"], "PR"
        )
        content = github_pull_request_content(payload)
    elif event == "issues":
        # in v1, we assume that this stream exists since it is
        # deprecated and the few realms that use it already have the
        # stream
        target_stream = issue_stream
        subject = get_pull_request_or_issue_subject(
            repository, payload["issue"], "Issue"
        )
        content = github_issues_content(payload)
    elif event == "issue_comment":
        # Comments on both issues and pull requests come in as issue_comment events
        issue = payload["issue"]
        if "pull_request" not in issue or issue["pull_request"]["diff_url"] is None:
            # It's an issues comment
            target_stream = issue_stream
            type = "Issue"
            subject = get_pull_request_or_issue_subject(
                repository, payload["issue"], type
            )
        else:
            # It's a pull request comment
            type = "PR"
            subject = get_pull_request_or_issue_subject(
                repository, payload["issue"], type
            )

        content = github_object_commented_content(payload, type)

    elif event == "push":
        subject, content = build_message_from_gitlog(
            user_profile,
            topic_focus,
            payload["ref"],
            payload["commits"],
            payload["before"],
            payload["after"],
            payload["compare"],
            payload["pusher"]["name"],
            forced=payload["forced"],
            created=payload["created"],
            deleted=payload["deleted"],
        )
    elif event == "commit_comment":
        subject = topic_focus

        comment = payload.get("comment")
        action = "[commented]({})".format(comment["html_url"])
        content = get_commits_comment_action_message(
            comment["user"]["login"],
            action,
            comment["html_url"].split("#", 1)[0],
            comment["commit_id"],
            comment["body"],
        )

    else:
        raise UnknownEventType(
            force_str("Event %s is unknown and cannot be handled" % (event,))
        )

    return target_stream, subject, content