7

I'm trying to do the equivalent of git log filename in a git bare repository using pygit2. The documentation only explains how to do a git log like this:

from pygit2 import GIT_SORT_TIME
for commit in repo.walk(oid, GIT_SORT_TIME):
    print(commit.hex)

Do you have any idea?

Thanks

EDIT:

I'm having something like this at the moment, more or less precise:

from pygit2 import GIT_SORT_TIME, Repository


repo = Repository('/path/to/repo')

def iter_commits(name):
    last_commit = None
    last_oid = None

    # loops through all the commits
    for commit in repo.walk(repo.head.oid, GIT_SORT_TIME):

        # checks if the file exists
        if name in commit.tree:
            # has it changed since last commit?
            # let's compare it's sha with the previous found sha
            oid = commit.tree[name].oid
            has_changed = (oid != last_oid and last_oid)

            if has_changed:
                yield last_commit

            last_oid = oid
        else:
            last_oid = None

        last_commit = commit

    if last_oid:
        yield last_commit


for commit in iter_commits("AUTHORS"):
    print(commit.message, commit.author.name, commit.commit_time)
user1415785
  • 342
  • 4
  • 13

2 Answers2

1

I would recommend you to just use git's command-line interface, which can provide nicely formatted output that is really easy to parse using Python. For example, to get the author name, log message and commit hashes for a given file:

import subprocess
subprocess.check_output(['git','log','--pretty="%H,%cn%n----%B----"','some_git_file.py'])

For a full list of format specifiers that you can pass to --pretty, have a look at the documentation of git log: https://www.kernel.org/pub/software/scm/git/docs/git-log.html

ThePhysicist
  • 1,822
  • 16
  • 21
0

Another solution, lazily yields revisions of a file from a given commit. Since it's recursive, it might break if the history is too large.

def revisions(commit, file, last=None):
    try:
        entry = commit.tree[file]
    except KeyError:
        return
    if entry != last:
        yield entry
        last = entry
    for parent in commit.parents:
        for rev in revisions(parent, file, last):
            yield rev
Scott
  • 4,070
  • 3
  • 21
  • 16