2013-05-30 71 views
0

我有一個腳本,我試圖運行來檢查最新的提交中的文件的編碼。當我手動運行它時,它的行爲如預期,但是當我執行提交時,它不會。如果它們不在我的函數中,我可以打印變量,所以我懷疑它與檢索修改/添加文件的方式有關。有沒有辦法做到Git可以更好地處理?Git預提交腳本不返回非零

#!/usr/bin/env python 

import chardetect, subprocess, os 
from sys import stdin, exit 
from chardet.universaldetector import UniversalDetector 

confidenceLevel = 0.8 
allowedEncoding = ('ascii', 'utf-8') 

# Get the current path and modify it to be the path to the repo 
filePath = os.path.dirname(os.path.realpath(__file__)) 
filePath = filePath.replace('.git/hooks', '') 

# Get all files that have been added or modified (filter is missing 'D' so that deleted files don't come through) 
pr = subprocess.Popen(['/usr/bin/git', 'diff', '--diff-filter=ACMRTUXB', '--cached', '--name-only'],     
     cwd=os.path.dirname('../../'), 
     stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE, 
     shell=False) # Take note: Using shell=True has significant security implications. 
(out, error) = pr.communicate() 

# Create a list of files to check 
out = out.split('\n') 
out = [item for item in out if item != ''] 
out = [filePath + item for item in out] 

messageList = [] # Keep this global 

# If no paths are provided, it takes its input from stdin. 
def description_of(file, name='stdin'): 
    #Return a string describing the probable encoding of a file. 
    u = UniversalDetector() 
    for line in file: 
     u.feed(line) 
    u.close() 
    result = u.result 
    if result['encoding']: 
     itPasses = '' 
     if result['encoding'] in allowedEncoding and result['confidence'] >= confidenceLevel: 
      pass 
     else: 
      messageList.append('%s: FAILS encode test %s with confidence %s\nYou must convert it before committing.' % (name, result['encoding'], result['confidence'])) 
    else: 
     return '%s: no result' % name 


def main(): 
    if len(out) <= 0: 
     exit() 
    else: 
     for path in out: 
      description_of(open(path, 'rb'), path) 
     for item in messageList: 
      print item 
    if len(messageList) == 0: 
     exit() 
    else: 
     exit(1) 

if __name__ == '__main__': 
    main() 

回答

1

在你的腳本的問題是這一行:

cwd=os.path.dirname('../../'), 

的鉤子你.git目錄內運行,而不是鉤子目錄內。所以你要離開回購與給定的線。關於此的更多細節可以在這裏找到in this answer。所以你不需要改變git diff --cached的密碼。

您可能需要更改cwd,以便您輸入UniversalDetector的路徑有意義。但是你在那裏做什麼是錯的。您不應該檢查工作目錄文件,而是檢查索引中的文件,因爲它們實際上將被提交。

您應該使用git ls-files --stagedgit show來獲取索引的內容。簡寫爲git show :filename,但這可能會導致配置文件較亂。

同時爲git diff添加-z的參數,所以你可以處理更多的文件名。

+0

具有完美的感覺。多麼不尋常的操作方式。現在,當我運行'git ls-files --stage'時,我得到了所有文件,包括那些未修改的文件。我真的只想添加/修改文件。我誤解了你的答案嗎? – Sneagan

+0

是的,你是:)。你應該使用你的diff命令(加上一個'-z')來獲取已更改文件的列表。但是,然後使用'git ls-files --stage'來獲取將要提交的版本。然後使用'git show'來獲取這些內容。 – Chronial

+0

哦,我明白了。我不需要那麼多的細節(至少我不認爲我會這樣做),因爲我想在這裏完成我想要完成的任務。不過感謝您的詳細解答! – Sneagan