2017-08-24 29 views
0

我使用git rev-list --all --format="%H%n%B"來檢索git存儲庫的所有(可達)提交。以機器可讀格式獲取git revlist的輸出

我需要能夠產生的輸出解析成單獨的字段爲提交散列以及所述生體

- >是否有任何強大的方式來格式化輸出的方式,以便它可以被解析?

雖然提交散列的長度是固定的,但是原始文本的行數不確定,因此需要某種分隔符。我想過用xml的標籤包裝輸出,例如--format="<record>%H%n%B</record>",但是這具有明顯的缺點,即如果將字符串</record>插入到原始體中,將會使解析器制動。當然,我可以使分隔符更加複雜,以減少將某人插入到提交消息中的風險,但我真正需要的是一個角色,在技術上不能成爲原始主體的一部分。我試圖使用ASCII控制字符作爲記錄分隔符「\ x1F」。但是,它並沒有像預期那樣插入輸出,而是照原樣打印。


基於從託雷克回覆(謝謝!)我是能夠創建一個小的Python函數:

from subprocess import Popen, PIPE 
from codecs import decode 

directory = '/path/to/git/repo' 

git_rev_list = Popen(['git', '-C', directory, 'rev-list', '--all'], stdout=PIPE) 
git_cat_file = Popen(['git', '-C', directory, 'cat-file', '--batch'], 
        stdin=git_rev_list.stdout, stdout=PIPE) 
while True: 
    line = git_cat_file.stdout.readline() 
    try: 
     hash_, type_, bytes_ = map(decode, line.split()) 
    except ValueError: 
     break 
    content = decode(git_cat_file.stdout.read(int(bytes_))) 
    if type_ == 'commit': 
     yield _get_commit(hash_, content) 
    git_cat_file.stdout.readline() 

回答

2

要通過格式插入一個ASCII RS,使用%x1F,不\x1F

一般來說,你最好的選擇是單獨進行身體檢索,因爲%B可以從字面上擴展到任何東西,並且沒有可用的保護。對於每次執行一次,通常很容易運行git log --no-walk --pretty=format:%B,但速度很慢。

爲了加速這一過程可以使用git cat-file --batch或類似,其不提供一種簡單的方式來分析在一個程序中的數據:每個對象由它的大小之前。提交對象很容易解析,因爲%B等價物只是「前兩個相鄰換行符之後的所有內容」。因此,而不是:

git rev-list --all --format=something-tricky | ... 

你可以使用:

git rev-list --all | git cat-file --batch | ... 

和改變預期的輸入格式期待的<hash> <type> <size-in-bytes> LF <bytes>序列。或者,將格式指令添加到git cat-file以消除對象類型(但我會保留它,因爲這意味着您可以告訴除註釋標記之外的提交)。 「

+0

>」但我會保留它,因爲這意味着你可以告訴提交除了註釋標籤「 這真的是一個問題?我添加了一些帶註釋的標籤來提交,但它們不會在'git rev-list --all'中顯示出來。 –

+1

默認情況下,no('git rev-list'只打印提交的散列ID,除非你給它'--objects',然後它會添加會混淆'git cat-file'的信息)。如果您要將'git cat-file'提供給'git rev-parse'的輸出,您可以獲取標籤,而在某些情況下您可能需要這樣做。 – torek

0

你是用「\ x1F的」在正確的道路上,但它應該是「%x1F」,你很好走。

從git的轉速名單的手冊頁:

· %x00: print a byte from a hex code

相關問題