2016-11-27 86 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