Option remorques dans git - optionpretty
J'essayais d'extraire un résumé des contributions de git log et d'en créer un résumé concis et d'en créer un excel / csv pour présenter des rapports.
J'ai essayé
git log --after="2020-12-10" --pretty=format:'"%h","%an","%ae","%aD","%s","(trailers:key="Reviewed By")"'
et le CSV ressemble à une colonne CSV vide à la fin.
...
"7c87963cc","XYZ","[email protected]","Tue Dec 8 17:40:13 2020 +0000","[TTI] Add support for target hook in compiler.", ""
...
et le git log
ressemble à quelque chose comme
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
Ce que je ne pouvais pas réussir, c'était d'extraire la Differential Revision
chaîne à l'aide de la (trailers:key="Reviewed By")
commande.
Je n'ai pas trouvé grand-chose sur la façon de faire fonctionner cela. J'ai vérifié le manuel de git et j'ai essayé ce qu'il explique.
Y a-t-il quelque chose qui me manque peut-être dans cette commande? La sortie attendue doit avoir le texte https://codereviews.com/DD8822
à la dernière position dans la sortie CVS ci-dessus.
Réponses
Je ne suis pas sûr mais:
- les clés de fin ne peuvent pas avoir d'espaces (donc
Reviewed By
->Reviewed-By
etDifferential Revision
->Differential-Revision
); - les bandes-annonces ne doivent pas être délimitées par de nouvelles lignes, mais séparées du message de validation de validation (par conséquent,
Reviewed By
votre question n'est pas considérée comme une bande-annonce).
Je ne recommanderais pas non plus d'utiliser CSV, mais d'utiliser TSV à la place: la sortie git n'est pas consciente de la syntaxe CSV (les points-virgules et les virgules s'échappant), par conséquent, le document de sortie peut être généré de manière non analysable.
Si vos messages de validation ressemblent à ceci ( -
au lieu d'espaces, pas de nouveaux délimiteurs de ligne):
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
Ensuite, la commande suivante fonctionnerait pour vous:
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)'
produire un identifiant de validation court, le nom de l'auteur, l'adresse e-mail de l'auteur, la date, le message de validation, la bande Reviewed-By
-annonce et la bande-annonce Differential-Revision
dans votre sortie de valeurs séparées par des tabulations
Si vous ne pouvez pas changer l'ancien commits parce que votre histoire n'est pas sûr pour ce faire (il est publié, tiré par les pairs, vos outils sont liés aux publiés commettre hash), alors vous devez traiter la git log
sortie avec sed
, awk
, perl
ou tout autre outil de transformation de texte pour générer votre rapport. Dites, traitez quelque chose comme git log --pretty=format:'%x02%h%x1F%an%x1F%ae%x1F%aD%x1F%s%x1F%n%B'
où les lignes entre ^B
(STX) et EOF devraient être analysées d'une manière ou d'une autre (filtrées pour les bandes-annonces qui vous intéressent), puis jointes à leurs lignes de groupe en commençant par ^B
, puis le caractère remplacé pour remplacer les séparateurs de champ et d'entrée par \t
et non caractère respectivement.
Mais encore une fois, si vous pouvez modifier l'historique en corrigeant les bandes-annonces de messages de validation (je ne sais pas dans quelle mesure cela peut affecter), je vous recommande de le faire, puis de rejeter l'idée de scripts supplémentaires traitant les bandes-annonces qui ne sont pas reconnues par git-interpret-trailers
et de simplement corriger le commettre des messages.
Modifier 1 (outils de texte)
Si la réécriture de l'historique n'est pas une option, l'implémentation de certains scripts peut vous aider. Je suis assez faible pour écrire des scripts / sed
/ puissants , mais laissez-moi essayer.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'
Comment ça fonctionne:
git
génère un journal composé de données délimitées avec des codes C0 C1 standard en supposant qu'il n'y a pas de tels caractères vos messages de validation (STX, RS et US - je ne sais pas vraiment si c'est un bon endroit pour les utiliser comme ça et si je les applique sémantiquement correct);gawk
filtre la sortie du journal en essayant d'analyser les groupes démarrés par STX et d'extraire les remorques, générant une sortie «à deux rangées» (chaque ligne impaire pour les données régulières, chaque ligne paire pour les valeurs de fin de fin jointes par des virgules même pour les remorques manquantes);sed
joint les lignes paires et impaires par paires (les crédits reviennent à Karoly Horvath );sed
supprime STX et RS;sed
remplace US par TAB.
Voici le trailers.awk
(encore une fois, je ne suis pas un awk
gars et je n'ai aucune idée à quel point le script suivant est idiomatique, mais cela semble fonctionner):
#!/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()
}
Quelques mots sur le fonctionnement du awk
script:
- il suppose que les enregistrements qui ne nécessitent pas de traitement commencent par STX;
- il essaie sur
grep
chaque ligne non "STX" unKey Name: Value
motif et enregistre le résultat trouvé dans un tableau temporaireTRAILERS
(qui sert en fait de multi-carte, commeMap<String, List<String>>
en Java) pour chaque enregistrement; - chaque enregistrement est écrit tel quel, mais les bandes-annonces sont écrites soit avant la détection d'un nouvel enregistrement, soit à l'EOF.
Edit 2 (mieux awk
)
Eh bien, je suis vraiment faible awk
, donc une fois que j'ai lu plus sur awk
les variables internes, j'ai compris que le awk
script pouvait être entièrement réimplémenté et produire lui-même une sortie de type TSV prête à l'emploi sans aucun post-traitement avec sed
ou perl
. La version plus courte et améliorée du script est donc:
#!/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: ")
}
Beaucoup plus concis, plus facile à lire, à comprendre et à maintenir.