Opsi cuplikan dalam opsi git --pretty
Saya mencoba mengekstrak ringkasan kontribusi dari git log dan membuat ringkasan singkat tentang itu dan membuat excel / csv darinya untuk menyajikan laporan.
Saya sudah mencoba
git log --after="2020-12-10" --pretty=format:'"%h","%an","%ae","%aD","%s","(trailers:key="Reviewed By")"'
dan CSV tampak seperti kolom CSV kosong di bagian akhir.
...
"7c87963cc","XYZ","[email protected]","Tue Dec 8 17:40:13 2020 +0000","[TTI] Add support for target hook in compiler.", ""
...
dan git log
terlihat seperti itu
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
Apa yang saya tidak bisa berhasil adalah mengekstrak Differential Revision
string menggunakan (trailers:key="Reviewed By")
perintah.
Saya tidak dapat menemukan banyak tentang bagaimana membuat ini bekerja. Saya memeriksa manual git dan saya mencoba apa yang dijelaskannya.
Apakah ada sesuatu yang mungkin saya lewatkan dalam perintah ini? Keluaran yang diharapkan harus memiliki teks https://codereviews.com/DD8822
pada posisi terakhir dalam keluaran CVS di atas.
Jawaban
Saya tidak yakin tapi:
- kunci trailer tidak boleh memiliki spasi putih (oleh karena itu
Reviewed By
->Reviewed-By
, danDifferential Revision
->Differential-Revision
); - cuplikan tidak boleh dibatasi oleh baris baru, tetapi dipisahkan dari pesan komit komit (oleh karena itu
Reviewed By
dari pertanyaan Anda tidak dianggap sebagai cuplikan).
Saya juga tidak akan merekomendasikan menggunakan CSV, tetapi menggunakan TSV sebagai gantinya: keluaran git tidak mengetahui sintaks CSV (titik koma dan pelolosan koma), oleh karena itu dokumen keluaran dapat dihasilkan tidak dapat diuraikan.
Jika pesan komit Anda akan terlihat seperti ini ( -
bukan spasi, tidak ada pembatas baris baru):
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
Maka perintah berikut akan bekerja untuk Anda:
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)'
menghasilkan id komit pendek, nama penulis, email penulis, tanggal, pesan komit, cuplikan Reviewed-By
, dan cuplikan Differential-Revision
ke keluaran nilai yang dipisahkan tab Anda.
Jika Anda tidak dapat mengubah lama pesan komit karena sejarah Anda tidak aman untuk melakukan hal ini (itu diterbitkan, ditarik oleh rekan-rekan, alat Anda terikat untuk hash diterbitkan komit), maka Anda harus memproses git log
output dengan sed
, awk
, perl
, atau alat pengubah teks lainnya untuk menghasilkan laporan Anda. Katakanlah, proses sesuatu seperti di git log --pretty=format:'%x02%h%x1F%an%x1F%ae%x1F%aD%x1F%s%x1F%n%B'
mana garis antara ^B
(STX) dan EOF harus dianalisis entah bagaimana (difilter untuk trailer yang Anda minati), lalu bergabung dengan garis grup mereka yang dimulai dengan ^B
, dan kemudian karakter diganti untuk mengganti pemisah bidang dan entri dengan \t
dan tidak karakter masing-masing.
Tetapi sekali lagi, jika Anda dapat mengedit riwayat dengan memperbaiki cuplikan pesan komit (tidak yakin seberapa besar pengaruhnya), saya sarankan Anda melakukannya dan kemudian menolak gagasan trailer pemrosesan skrip tambahan yang tidak dikenali oleh git-interpret-trailers
dan hanya memperbaiki melakukan pesan.
Edit 1 (alat teks)
Jika menulis ulang sejarah bukanlah suatu pilihan, maka menerapkan beberapa skrip dapat membantu Anda. Aku cukup lemah dalam menulis skrip / sed
/ yang kuat , tapi biarkan aku mencobanya.awk
perl
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'
Bagaimana itu bekerja:
git
menghasilkan log yang terbuat dari data yang dibatasi dengan kode C0 C1 standar dengan asumsi tidak ada karakter seperti itu pada pesan komit Anda (STX, RS dan AS - saya tidak begitu tahu apakah itu tempat yang baik untuk menggunakannya seperti itu dan jika saya menerapkannya benar secara semantik);gawk
memfilter keluaran log yang mencoba mengurai grup yang dimulai STX dan mengekstrak cuplikannya, menghasilkan keluaran "dua baris" (setiap baris ganjil untuk data biasa, setiap baris genap untuk nilai cuplikan yang digabungkan koma, bahkan untuk cuplikan yang hilang);sed
menggabungkan garis ganjil dan genap secara berpasangan (kredit diberikan ke Karoly Horvath );sed
menghapus STX dan RS;sed
menggantikan AS ke TAB.
Ini dia trailers.awk
(sekali lagi saya bukan awk
laki - laki dan tidak tahu betapa idiomatisnya skrip berikut ini, tetapi tampaknya berfungsi):
#!/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()
}
Beberapa kata tentang cara kerja awk
skrip:
- ini mengasumsikan bahwa rekaman yang tidak memerlukan pemrosesan dimulai dengan STX;
- ia mencoba untuk
grep
setiap baris non- "STX" untuk sebuahKey Name: Value
pola dan menyimpan hasil yang ditemukan ke array sementaraTRAILERS
(yang sebenarnya berfungsi sebagai multimap, sepertiMap<String, List<String>>
di Java) untuk setiap record; - setiap catatan ditulis apa adanya, tetapi cuplikan ditulis sebelum mendeteksi catatan baru atau di EOF.
Edit 2 (lebih baik awk
)
Yah, saya benar-benar lemah awk
, jadi setelah saya membaca lebih lanjut tentang awk
variabel internal, saya menemukan awk
skrip dapat diimplementasikan kembali sepenuhnya dan menghasilkan output seperti TSV yang siap digunakan itu sendiri tanpa pemrosesan pasca dengan sed
atau perl
. Jadi versi skrip yang lebih pendek dan lebih baik adalah:
#!/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: ")
}
Jauh lebih ringkas, lebih mudah dibaca, dipahami, dan dipelihara.