2012-06-07 52 views
2

我在Git倉庫上運行Gitolite,並且我有用Python編寫的post-receive鉤子。我需要在git repository目錄下執行「git」命令。有幾行代碼:通過git鉤子執行python子進程

proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git' stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
proc.communicate() 

後,我作出新的承諾,並推到庫,腳本執行,並說

fatal: Not a git repository: '.' 

如果我運行

proc = subprocess.Popen(['pwd'], cwd='/home/git/repos/testing.git' stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

它說,如預期,正確的路徑到git倉庫(/home/git/repos/testing.git)

如果我從bash手動運行這個腳本,它工作正常並顯示正確的「git log」輸出。我做錯了什麼?

回答

4

你可以嘗試使用命令行開關來設置Git倉庫:

proc = subprocess.Popen(['git', '--git-dir', '/home/git/repos/testing.git', 'log', '-n1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

--git-dir需要指向一個實際git目錄(工作樹中的.git)。請注意,對於某些命令,您還需要也設置--work-tree選項。

另一種方式來設置目錄使用GIT_DIR環境變量:

import os 
env = os.environ.copy() 
env['GIT_DIR'] = '/home/git/repos/testing.git' 
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) 

顯然已經的鉤設置GIT_DIR,但顯然這是不正確的你的情況(也可能是相對的);上面的代碼將其設置爲完整的顯式路徑。

請參閱git manpage

編輯:顯然,它同時指定一個CWD和重寫GIT_DIR VAR時,僅適用於在OP:

import os 
repo = '/home/git/repos/testing.git' 
env = os.environ.copy() 
env['GIT_DIR'] = repo 
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, cwd=repo) 
+1

鉤子已經設置好環境變量'$ GIT_DIR',所以如果你想把git指向不同的目錄,你必須重寫它。請注意,一般情況下,鉤子也運行'GIT_DIR = .'(即它是*相對*,這對我來說是一個驚喜)。最好完全清除它或將其設置爲你想要的。 – torek

+0

@torek:有趣的是,這可能是OP的錯誤。更新了答案,因爲'env.update(os.environ)'會抹掉我們試圖設置的自定義'GIT_DIR' var。 –

+0

呵呵,我沒有仔細閱讀你的第二部分答案,以至於你意識到你正在使用'.update'。無論如何,是的,我懷疑這是OP的真正問題。 (實驗告訴我,' - git-dir'覆蓋了'$ GIT_DIR',所以你的第一個答案應該可以工作。) – torek

0

有一個逗號CWD爭吵後失蹤:

proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git', stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
+1

這很難吧;這會產生一個SyntaxError,而不是用戶看到的錯誤。在SO上發佈時,可以避免轉換錯誤。 –