6

I want to copy files from specified commit with GitPython. Now I come here so far:

import git
git = git.Git(REPO_PATH)
git.checkout(COMMIT_HEX_SHA)
fo = open(REPO_PATH + "/foo.txt", "r")
str = fo.read(10);
fo.close()

It works. But checkout changes HEAD and changes files. Is it possible to copy files or read files from specified commit without checkout?

gzc
  • 8,180
  • 8
  • 42
  • 62
  • 2
    It should be possible to use obtain a blob from any commit and read from it, e.g. `git.Repo().commit(COMMIT_HEX_SHA).tree['subdir/somefile.ext'].data_stream`. – Byron Dec 07 '15 at 16:02

2 Answers2

1

Byron's comment does indeed give you a stream, but a word of caution: If you're used to using a with-as construct or .readlines() to read streams, don't try them here. Go for plain .read().

git.Repo().commit(COMMIT_HEX_SHA).tree['subdir/somefile.ext'].data_stream.read()

If you don't want the trailing newline, you can also delegate directly to git show like shown here:

git.Repo().git.show(f'{COMMIT_HEX_SHA}:{file_with_path}')
Michael
  • 8,362
  • 6
  • 61
  • 88
1

I'd suggest you to use PyDriller (it uses GitPython internally). It's much easier to use:

for commit in RepositoryMining("path_to_repo", single="commitHASH").traverse_commits():
    for modified_file in commit.modifications:
        # do whatever you want with the source code
        print(modified_file.source_code)
Davide Spadini
  • 271
  • 2
  • 7