Tùy chọn đoạn giới thiệu trong tùy chọn git --pretty
Tôi đang cố gắng trích xuất một bản tóm tắt các đóng góp từ nhật ký git và tạo một bản tóm tắt ngắn gọn về điều đó và tạo một excel / csv từ đó để trình bày báo cáo.
Tôi đã thử
git log --after="2020-12-10" --pretty=format:'"%h","%an","%ae","%aD","%s","(trailers:key="Reviewed By")"'
và CSV trông giống như với một cột CSV trống ở cuối.
...
"7c87963cc","XYZ","[email protected]","Tue Dec 8 17:40:13 2020 +0000","[TTI] Add support for target hook in compiler.", ""
...
và git logcái gì đó trông giống như
commit 7c87963cc
Author: XYZ <[email protected]>
Date: Tue Dec 8 17:40:13 2020 +0000
[TTI] Add support for target hook in compiler.
This adds some code in the TabeleGen ...
This is my body of commit.
Reviewed By: Sushant
Differential Revision: https://codereviews.com/DD8822
Điều tôi không thể thành công là giải nén Differential Revisionchuỗi bằng (trailers:key="Reviewed By")lệnh.
Tôi không thể tìm thấy nhiều về cách làm cho điều này hoạt động. Tôi đã kiểm tra hướng dẫn sử dụng git và tôi đã thử những gì nó giải thích.
Có điều gì tôi có thể thiếu trong lệnh này? Đầu ra mong đợi phải có văn bản https://codereviews.com/DD8822ở vị trí cuối cùng trong đầu ra CVS ở trên.
Trả lời
Tôi không chắc nhưng:
- khóa trailer không được có khoảng trắng (do đó
Reviewed By->Reviewed-By, vàDifferential Revision->Differential-Revision); - các đoạn giới thiệu không nên được phân cách bằng các dòng mới, nhưng được phân tách khỏi thông báo cam kết cam kết (do đó
Reviewed Bytừ câu hỏi của bạn không được coi là đoạn giới thiệu).
Tôi cũng không khuyên bạn nên sử dụng CSV, nhưng sử dụng TSV thay thế: đầu ra git không biết về cú pháp CSV (dấu chấm phẩy và dấu phẩy thoát ra), do đó, tài liệu đầu ra có thể được tạo ra không thể phân tích được.
Nếu thông báo cam kết của bạn trông giống như thế này ( -thay vì dấu cách, không có dấu phân cách dòng mới):
commit 7c87963cc
Author: XYZ <[email protected]>
Date: Tue Dec 8 17:40:13 2020 +0000
[TTI] Add support for target hook in compiler.
This adds some code in the TabeleGen ...
This is my body of commit.
Reviewed-By: Sushant
Differential-Revision: https://codereviews.com/DD8822
Sau đó, lệnh sau sẽ làm việc cho bạn:
git log --pretty=format:'%h%x09%an%x09%ae%x09%aD%x09%s%x09%(trailers:key=Reviewed-By,separator=%x20,valueonly)%x09%(trailers:key=Differential-Revision,separator=%x20,valueonly)'
tạo id cam kết ngắn, tên tác giả, email tác giả, ngày tháng, thông điệp cam kết, đoạn giới thiệu Reviewed-Byvà đoạn giới thiệu Differential-Revisioncho đầu ra các giá trị được phân tách bằng tab của bạn.
Nếu bạn có thể không thay đổi cái cũ cam kết bài vì lịch sử của bạn là không an toàn để làm điều này (nó đã được xuất bản, kéo bởi đồng nghiệp, các công cụ của bạn đang bị ràng buộc để băm xuất bản cam kết), sau đó bạn phải xử lý git logđầu ra với sed, awk, perl, hoặc bất kỳ công cụ chuyển đổi văn bản khác để tạo báo cáo của bạn. Giả sử, xử lý một cái gì đó như git log --pretty=format:'%x02%h%x1F%an%x1F%ae%x1F%aD%x1F%s%x1F%n%B'trong đó các dòng giữa ^B(STX) và EOF nên được phân tích bằng cách nào đó (được lọc cho các đoạn giới thiệu mà bạn quan tâm), sau đó tham gia vào các dòng nhóm của chúng bắt đầu bằng ^Bvà sau đó ký tự được thay thế để thay thế các dấu phân tách trường và mục nhập bằng \tvà không ký tự tương ứng.
Nhưng một lần nữa, nếu bạn có thể chỉnh sửa lịch sử bằng cách sửa đoạn giới thiệu thông báo cam kết (không chắc nó có thể ảnh hưởng đến mức độ nào), tôi khuyên bạn nên làm điều đó và sau đó từ chối ý tưởng về các đoạn mã bổ sung xử lý đoạn giới thiệu không được nhận dạng git-interpret-trailersvà chỉ cần sửa lỗi cam kết tin nhắn.
Chỉnh sửa 1 (công cụ văn bản)
Nếu việc viết lại lịch sử không phải là một lựa chọn, thì việc triển khai một số tập lệnh có thể giúp ích cho bạn. Tôi khá yếu trong việc viết các tập lệnh / sed/ mạnh mẽ , nhưng hãy để tôi thử.awkperl
git log --pretty=format:'%x02%h%x1F%an%x1F%ae%x1F%aD%x1F%s%x1F%n%B' \
| gawk -f trailers.awk \
| sed '$!N;s/\n/\x1F/' \
| sed 's/[\x02\x1E]//g' \
| sed 's/\x1F/\x09/g'
Làm thế nào nó hoạt động:
gittạo nhật ký làm bằng dữ liệu được phân tách bằng mã C0 C1 tiêu chuẩn giả sử không có ký tự nào như vậy trong thông điệp cam kết của bạn (STX, RS và US - Tôi thực sự không biết liệu có nên sử dụng chúng như vậy không và liệu tôi có áp dụng chúng không đúng ngữ nghĩa);gawklọc đầu ra nhật ký cố gắng phân tích cú pháp các nhóm bắt đầu bằng STX và trích xuất các đoạn giới thiệu, tạo ra đầu ra "hai hàng" (mỗi dòng lẻ cho dữ liệu thông thường, mỗi dòng chẵn cho các giá trị đoạn giới thiệu được kết hợp bằng dấu phẩy ngay cả cho đoạn giới thiệu bị thiếu);sednối các dòng lẻ và dòng chẵn theo cặp (các khoản tín dụng thuộc về Karoly Horvath );sedloại bỏ STX và RS;sedthay thế US thành TAB.
Đây là trailers.awk(một lần nữa tôi không phải là một awkchàng trai và không biết kịch bản sau nó thành ngữ như thế nào, nhưng nó có vẻ hoạt động):
#!/usr/bin/awk -f
BEGIN {
FIRST = 1
delete TRAILERS
}
function print_joined_array(array) {
if ( !length(array) ) {
return
}
for ( i in array ) {
if ( i > 0 ) {
printf(",")
}
printf("%s", array[i])
}
printf("\x1F")
}
function print_trailers() {
if ( FIRST ) {
FIRST = 0
return
}
print_joined_array(TRAILERS["Reviewed By"])
print_joined_array(TRAILERS["Differential Revision"])
print ""
}
/^\x02/ {
print_trailers()
print $0
delete TRAILERS
}
match($0, /^([-_ A-Za-z0-9]+):\s+(.*)\s*/, M) {
TRAILERS[M[1]][length(TRAILERS[M[1]])] = M[2]
}
END {
print_trailers()
}
Một vài từ về cách awkhoạt động của tập lệnh:
- nó giả định rằng các bản ghi không yêu cầu xử lý đang bắt đầu bằng STX;
- nó cố gắng đến
greptừng dòng không phải là "STX" cho mộtKey Name: Valuemẫu và lưu kết quả tìm được vào một mảng tạm thờiTRAILERS(thực sự phục vụ như một bản đồ đa năng, giống nhưMap<String, List<String>>trong Java) cho mỗi bản ghi; - mỗi bản ghi được ghi như hiện tại, nhưng đoạn giới thiệu được viết trước khi phát hiện bản ghi mới hoặc tại EOF.
Chỉnh sửa 2 (tốt hơn awk)
Chà, tôi thực sự yếu awk, vì vậy khi tôi đọc thêm về awkcác biến bên trong, tôi đã tìm ra awkkịch bản có thể được thực hiện lại hoàn toàn và tạo ra một đầu ra giống TSV sẵn sàng sử dụng mà không cần bất kỳ xử lý hậu kỳ nào với sedhoặc perl. Vì vậy, phiên bản ngắn hơn và cải tiến của tập lệnh là:
#!/bin/bash
git log --pretty=format:'%x1E%h%x1F%an%x1F%ae%x1F%aD%x1F%s%x1F%B%x1E' \
| gawk -f trailers.awk
#!/usr/bin/awk -f
BEGIN {
RS = "\x1E"
FS = "\x1F"
OFS = "\x09"
}
function extract(array, trailer_key, __buffer) {
for ( i in array ) {
if ( index(array[i], trailer_key) > 0 ) {
if ( length(__buffer) > 0 ) {
__buffer = __buffer ","
}
__buffer = __buffer substr(array[i], length(trailer_key))
}
}
return __buffer
}
NF > 1 {
split($6, array, "\n")
print $1, $2, $3, $4, $5, extract(array, "Reviewed By: "), extract(array, "Differential Revision: ")
}
Ngắn gọn hơn, dễ đọc, dễ hiểu và dễ bảo trì hơn.