2016-11-27 89 views
1

我需要讓一個分支中的所有更改由實現特殊部署邏輯的應用程序進一步處理。因爲它可能是微不足道的額外git log - 如何獲取xml輸出

  • 提交SHA1
  • 提交日期
  • 被修改的文件列表和改變類型爲每個


至少,我需要得到獲得:

  • 提交人作者
  • 承諾筆記

想抓住這些。輸出需要是XML。

我知道那裏有perl腳本會創建一個JSON輸出,但我想堅持使用XML。

我試過很格式選項,但找不到變動的佔位符,並運行
git log -10 --name-status --pretty=format:"<entry><author>%an</author><commit_date>%cd</commit_date><message_body>%N</message_body></entry>" -- databases/
只是轉儲條目之間的變化...

我寫的解析awk腳本輸出,但希望找到更「原生」的東西。那裏有東西嗎?也許我錯過了一個選項?

對於任何如此感興趣的人來說,這裏是一個awk腳本,可以做我想做的事情。還不確定爲什麼它需要在mac上運行,但在cygwin中運行得很好。

# script to parse the output of git log --name-status 
BEGIN{ 
    RS="commit "; 
    FS="\n"; 
    print "<log>"; 
} 

NR>1{ 
    StartComment=0; 
    CommentText = ""; 
    CommitText = ""; 
    AuthorText = ""; 
    DateText = ""; 
    ChangesText = ""; 
    isLast = 0; 

for(i = 1; i <= NF; i++) 
{ 

if (i==1) {CommitText = $i;} 
    if (match($i,/^Author/)) { 
    #remove "author :" 
    split($i,author1,": "); 
    split(author1[2],author2," <") 
    AuthorText = author2[1];} 
    else if (match($i,/^Date/)) {StartComment=1; ln=i; 
    #remove "date :" 
    split($i,dt,": "); 
    DateText = dt[2]; 
    #trim whitespaces 
    gsub(/^[ \t]+/,"",DateText); 
     } 
    else if (match($i,/^[A-Z]\s/)) {StartComment=0; 
    if(match($i,/\.sql$/)){ 
     j = i+1 
     ch_path = substr($i,2) 
     gsub(/^[ \t]+/,"",ch_path); 
     unitChange = "\t\t\t<change>\n\t\t\t\t<ChangeType>"substr($i,1,1)"</ChangeType>\n\t\t\t\t<Path>"ch_path"</Path>\n\t\t\t</change>"; 
     ChangesText = ChangesText""unitChange; 
     if (!match($(j),/^$/)){ChangesText = ChangesText"\n"} 
    } 
    } 
    else if (StartComment==1 && i>ln) { {CommentText=CommentText$i"\n"} } 

} 

print "\t<entry>"; 
print "\t\t<commit-sha1>"CommitText"</commit-sha1>"; 
print "\t\t<Author>"AuthorText"</Author>"; 
print "\t\t<CommitDate>"DateText"</CommitDate>"; 
print "\t\t<Changes>"; 
print ChangesText; 
print "\t\t</Changes>"; 
print "\t</entry>";  
} 
END { 
    print "</log>" 
} 

回答

4

git log不會產生良好的XML,和消息體(%s%b%B)和註釋(%N)是自由形式的文本,因此可以含有無效的XML字符,如控制-L,尖括號,甚至字節序列<![CDATA[。 (如果你的XML編碼器沒有爲你處理它,這最後真的會讓你感到混亂,我從試圖連接到不同的VCS的經驗中得知,在這個VCS上有人粘貼了一個假的XML編碼器Perl腳本,它無法對消息日誌進行編碼僞造的編碼器用&lt;等取代了尖括號和&符號,但沒有處理控制字符,許多消息都有^ Ls-和CDATA,這些消息在一個消息中發生,當然,處理時XML)。

這意味着您應該編寫自己的編碼器。你可能在awk中做到這一點(我看到你包括一個awk標籤),雖然我可能不會自己。我會推薦使用base64或類似的方案編碼任意文本,如消息體和筆記。

(請注意,雖然是至少少見,Git的郵件正文甚至可以包括ASCII完全無效。)

+0

感謝,忽略編碼問題一秒鐘,有沒有辦法讓提交信息的XML包括更改從任何本地git命令? – Mordechai

+0

不,沒有修改Git源代碼。如果您願意折扣NUL的可能性,您可以在'--pretty = format:'格式的項目之間使用%x00,並使用它來區分(例如)%N和日誌消息用一個'git log'命令。但要確保100%的確定,例如,你必須使用'git log --no-walk --pretty = format:%N'來獲取單獨的音符。 – torek

+0

鑑於許多項*都受到限制(在作者和提交者名稱和日期中不會有新行或NUL),所以您可以在幾個獨立的'git日誌'中獲取所有內容。但是,對於對內容的原始訪問,您可能希望查看'git cat-file --batch-check',或許也使用format指令。您可以獲取大小,然後是原始字節,以便知道將多少個字節解釋爲內容。 – torek