在提交前抛出Git diff调用“致命:无法读取[SHA1]”

时间:2014-07-18 14:55:37

标签: python git githooks

我正在使用Windows并尝试在存储库的预提交脚本(Python)中运行git diff命令。我的Python调用如下所示:

repo_dir = 'D:/git/current_uic/src/gtc/resource'
cmd = ['diff', '--name-only']
print(Popen(['git', '--git-dir={}'.format(repo_dir + '/.git'), 
             '--work-tree={}'.format(repo_dir)] + cmd,
            stdin=PIPE, stdout=PIPE).communicate())

每当我去提交" D:/ git / current_uic / src / gtc"回购,我得到以下内容:

fatal: unable to read 6ff96bd371691b9e93520e133ebc4d84c74cd0f6

请注意,这是' D:/ git / current_uic / src / gtc'的预提交挂钩。存储库和那个' D:/ git / current_uic / src / gtc / resource'是' D:/ git / current_uic / src / gtc'的子模块。另请注意,如果我弹出Git bash并运行以下命令:

git --git-dir=D:/git/current_uic/src/gtc/resource/.git 
    --work-tree=D:/git/current_uic/src/gtc/resource diff --name-only

或者如果我直接从Git bash运行脚本,无论工作目录如何,我都能得到我想要的内容。

关于这里发生了什么的任何想法?

2 个答案:

答案 0 :(得分:1)

问题:

在运行钩子时,Git设置一些钩子脚本可以访问的环境变量。问题是Git本身使用这些环境变量,并且Git设置/使用它们的正常方式似乎被钩子被触发时设置的值所覆盖。在此特定实例中,环境变量GIT_INDEX_FILE已设置为与已调用挂钩的存储库对应的索引文件的路径(D:/git/current_uic/src/.git/modules/gtc/index ),导致(不正确)索引和(正确)更改树之间不匹配。

修复:

在钩子脚本中,在进行任何git调用之前,将环境变量GIT_INDEX_FILE设置为正确的值。在这种情况下,您可以执行以下操作:

set GIT_INDEX_FILE=D:/git/current_uic/src/.git/modules/gtc/modules/resource/index
git --git-dir=D:/git/current_uic/src/gtc/resource/.git 
    --work-tree=D:/git/current_uic/src/gtc/resource diff --name-only

其他信息

有关这些Git环境变量的更多信息以及设置它们的钩子可以找到here

答案 1 :(得分:0)

使用gitpython解决了完全相同的问题。 我是这样解决的:

repo = git.Repo()
for submodule in repo.submodules:
    back_index = os.getenv('GIT_INDEX_FILE')
    os.environ['GIT_INDEX_FILE'] = submodule.module().index.path
    commit = submodule.module().head.commit
    print([item.a_path for item in commit.diff(None)])
    os.environ['GIT_INDEX_FILE'] = back_index