from collections import namedtuple


LogEntry = namedtuple("LogEntry", (
    "short_hash",
    "long_hash",
    "summary",
    "raw_body",
    "author",
    "email",
    "datetime"
    ))


class HistoryMixin():

    def log(self, author=None, branch=None, file_path=None, start_end=None, cherry=None,
            limit=6000, skip=None, reverse=False, all_branches=False, msg_regexp=None,
            diff_regexp=None, first_parent=False, no_merges=False, topo_order=False):

        log_output = self.git(
            "log",
            "-{}".format(limit) if limit else None,
            "--skip={}".format(skip) if skip else None,
            "--reverse" if reverse else None,
            '--format=%h%n%H%n%s%n%an%n%ae%n%at%x00%B%x00%x00%n',
            "--author={}".format(author) if author else None,
            "--grep={}".format(msg_regexp) if msg_regexp else None,
            "--cherry" if cherry else None,
            "--G" if diff_regexp else None,
            diff_regexp if diff_regexp else None,
            "--first-parent" if first_parent else None,
            "--no-merges" if no_merges else None,
            "--topo-order" if topo_order else None,
            "--all" if all_branches else None,
            "{}..{}".format(*start_end) if start_end else None,
            branch if branch else None,
            "--" if file_path else None,
            file_path if file_path else None
        ).strip("\x00")

        entries = []
        for entry in log_output.split("\x00\x00\n"):
            entry = entry.strip()
            if not entry:
                continue
            entry, raw_body = entry.split("\x00")

            short_hash, long_hash, summary, author, email, datetime = entry.split("\n")
            entries.append(LogEntry(short_hash, long_hash, summary, raw_body, author, email, datetime))

        return entries

@@ -1853,8 +1853,1048 @@
 entries%0A
+%0A    def log1(self, commit_hash):%0A        %22%22%22%0A        Return a single LogEntry of a commit.%0A        %22%22%22%0A        return self.log(start_end=(%22%7B0%7D~1%22.format(commit_hash), commit_hash), limit=1)%5B0%5D%0A%0A    def log_merge(self, merge_hash):%0A        %22%22%22%0A        Return all LogEntry of a merge.%0A        %22%22%22%0A        ret = self.log(%0A            start_end=(%22%7B0%7D~1%22.format(merge_hash), merge_hash), topo_order=True, reverse=True)%0A        return ret%5B0:(len(ret)-1)%5D%0A%0A    def commits_of_merge(self, merge_hash):%0A        %22%22%22%0A        Return commits of a merge.%0A        %22%22%22%0A        return self.git(%0A            %22rev-list%22, %22--topo-order%22, %22%7B0%7D~1..%7B0%7D%22.format(merge_hash)).strip().split(%22%5Cn%22)%5B1:%5D%0A%0A    def commit_parents(self, commit_hash):%0A        %22%22%22%0A        Return parents of a commit.%0A        %22%22%22%0A        return self.git(%22rev-list%22, %22-1%22, %22--parents%22, commit_hash).strip().split(%22 %22)%5B1:%5D%0A%0A    def commit_is_merge(self, commit_hash):%0A        sha = self.git(%22rev-list%22, %22--merges%22, %22-1%22, %22%7B0%7D~1..%7B0%7D%22.format(commit_hash)).strip()%0A        return sha is not %22%22%0A

add history helper functions