我是GitPython的新手,我试图在提交中获取文件的内容。我能够从特定的提交中获取每个文件,但每次运行命令时都会收到错误。现在,我知道该文件存在于GitPython中,但每次运行我的程序时,都会出现以下错误:
returned non-zero exit status 1
我正在使用 Python 2.7.6 和 Ubuntu Linux 14.04。
我知道文件存在,因为我也从命令行直接进入git,检查相应的提交,搜索文件,然后找到它。我还在其上运行 cat 命令,并显示文件内容。很多时候,当错误出现时,它表示相关文件不存在。我试图通过GitPython进行每次提交,从每个单独的提交中获取每个blob或文件,并在该文件的内容上运行外部Java程序。 Java程序旨在将字符串返回给Python。要捕获从我的Java代码返回的字符串,我还使用 subprocess.check_output 。任何帮助将不胜感激。
我尝试将命令作为列表传递:
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava','absolute/path/to/file']
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
我还尝试将命令作为字符串传递:
subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
是否可以从GitPython访问文件的内容? 例如,假设有一个提交,它有一个文件 foo.java 在该文件中有以下代码行:
foo.java
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class foo{
public static void main(String[] args) throws Exception{}
}
我想访问文件中的所有内容并在其上运行外部程序。 任何帮助将不胜感激。下面是我正在使用的一段代码
#! usr/bin/env python
__author__ = 'rahkeemg'
from git import *
import git, json, subprocess, re
git_dir = '/home/rahkeemg/Documents/GitRepositories/WhereHows'
# make an instance of the repository from specified path
repo = Repo(path=git_dir)
heads = repo.heads # obtain the differnet repositories
master = heads.master # get the master repository
print master
# get all of the commits on the master branch
commits = list(repo.iter_commits(master))
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava']
# start at the very 1st commit, or start at commit 0
for i in range(len(commits) - 1, 0, -1):
commit = commits[i]
commit_num = len(commits) - 1 - i
print commit_num, ": ", commit.hexsha, '\n', commit.message, '\n'
for entry in commit.tree.traverse():
if re.search(r'\.java', entry.path):
current_file = str(entry.abspath.strip())
#add the current file, or blob, to the list for the command to run
cmd.append(current_file)
print entry.abspath
try:
#This is scenario where I pass arguments into command as a string
print subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
# scenario where I pass arguments into command as a list
j_response = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
except subprocess.CalledProcessError as e:
print "Error on file: ", current_file
#Use pop on list to remove the last string, which is the selected file at the moment, to make place for the next file.
cmd.pop()
答案 0 :(得分:8)
首先,当你像这样遍历提交历史时,不会检出该文件。你得到的只是文件名,可能是文件或可能不是,但肯定不会导致文件的修订版本与当前签出的文件不同。
然而,有一个解决方案。请记住,原则上,您可以使用某些git
命令执行任何操作,您可以使用GitPython。
要从特定修订获取文件内容,您可以执行以下操作:I've taken from that page:
git show <treeish>:<file>
因此,在GitPython中:
file_contents = repo.git.show('{}:{}'.format(commit.hexsha, entry.path))
但是,仍然不会使文件出现在磁盘上。如果您需要文件的实际路径,可以使用tempfile:
f = tempfile.NamedTemporaryFile(delete=False)
f.write(file_contents)
f.close()
# at this point file with name f.name contains contents of
# the file from path entry.path at revision commit.hexsha
# your program launch goes here, use f.name as filename to be read
os.unlink(f.name) # delete the temp file