4

I'm trying to use the GitPython module in my script... and I can't. That's not very documented : GitPython Blame

I think I'm not so far, because the normally git blame I want to reproduce is the follow : git blame -L127,+1 ../../core/src/filepath.cpp -e

Here is my script :

from git import *
    repo = Repo("C:\\Path\\to\\my\\repos\\")
    assert not repo.bare
    # log_line = open("lineDeb.txt")
    # for line in log_line:
    repo.git.blame(L='127,+1' '../../core/src/filepath.cpp', e=True)

The two lines commented are for the final goal to git blame on each number line in my "lineDeb.txt" file.

I've the following ouput :

...
git.exc.GitCommandError: 'git blame -L127,+1../../core/src/filepath.cpp -e' returned with exit code 129
stderr: 'usage: git blame [options] [rev-opts] [rev] [--] file
...

The goal is to get the email of the line committer...

2 Answers 2

5
for commit, lines in repo.blame('HEAD', filepath):
    print("%s changed these lines: %s" % (commit, lines))

The commit is the one that changed the given lines, in order of appearance in the file. Thus, if your would write all lines into a file, your would have the file at filepath at revision HEAD.

If you are looking for only a specific line, and as there are no options that you could currently pass to the blame subcommand, you would have to count to the line yourself.

ln = 127 # lines start at 0 here
tlc = 0

for commit, lines in repo.blame('HEAD', filepath):
    if tlc <= ln < (tlc + len(lines)):
         print(commit)
    tlc += len(lines)

This is less optimal than passing the respective -L option to git blame, but should do the job.

If it turns out to be too slow, you could consider making a PR that adds **kwargs to Repo.blame to pass on to git blame.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for answer. I've seen this command repo.blame('HEAD', filepath) but how I can blame only on specific line (127 for example) and get the email of the commiter ?
Python doesn't take the return commit... outside function. But just with print, that's work. Thanks.
1

If you're blaming a large number of lines you might find this higher performance:

blame = []
cmd = 'cd {path};git blame {fname}'.format(
            path=repo_path,
            fname=rootpath + fname)
with os.popen(cmd) as process:
   blame = process.readlines()

print blame[line_number]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.