Ich verwende Shell, um eine Git-Hook-Datei zu schreiben und meine Commit-Nachricht vor dem Commit zu überprüfen. Ich bin ein absoluter Anfänger und habe Folgendes versucht:
Meine commit-msg
Hook-Datei sieht wie folgt aus:
#!/bin/sh
msg=`head -n 1 $1`
if echo $msg | egrep -qv '(Android-\d{3,4}.{20,})'; then
echo "[Message Format] Your message is not formatted correctly. Correct message format\n
#Ticket Number - Minimum 20 or more Character \n
like #Android-123 Bug fixed for login issue"
exit 1;
fi
Wenn ich also eine Commit-Nachricht wie diese mache:
git commit -m " #Android-123 I pretty sure this is more than 20 character,but it still failed to commit"
Ich bin mir also ziemlich sicher, dass meine Commit-Nachricht mehr als 20 Zeichen und die Ticketnummer umfasst, aber bei jedem Commit erhalte ich trotzdem den von mir festgelegten Fehler.
Ich glaube, mein Logikproblem besteht darin, dass ich verwenden sollte if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})'
, also habe ich Folgendes versucht:
if ! [[echo $msg | egrep -qv '(Android-\d{3,4}.{20,})']] ;
then....
Aber das gibt mir diesen Fehler: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'
Frage:
Was habe ich falsch gemacht, sodass das Commit fehlgeschlagen ist, obwohl ich eine richtige Commit-Nachricht gesendet habe?
Wie kann ich es reparieren?
Antwort1
Ihr regulärer Ausdruck verwendet PCRE-Syntax wie \d
, aber grep -E
(das egrep
ist Ihr, aber verwenden Sie grep -E
stattdessen, egrep
wird veraltet) versteht das nicht. Außerdem brauchen Sie die Klammern dort nicht, Sie erfassen eigentlich nichts. Wenn Sie GNU haben grep
, können Sie grep -P
stattdessen Folgendes verwenden:
grep -Pqv 'Android-\d{3,4}.{20,}'
Wenn nicht, müssen Sie es \d
durch Folgendes ersetzen [0-9]
:
grep -Eqv 'Android-[0-9]{3,4}.{20,}'
Sie müssen (oder wollen) jedoch nicht nur die erste Zeile der Datei verwenden, sondern können die gesamte Datei direkt greppen. Sie müssen auch die Übereinstimmung ( -v
) nicht umkehren, das würde die Sache nur verkomplizieren. Hier ist eine einfachere, funktionierende Version Ihres Skripts, die verwendet wird, if !
um die Bedingung zu negieren:
#!/bin/sh
if ! grep -E 'Android-[0-9]{3,4}.{20,}' "$1"; then
printf "[Message Format] Your message is not formatted correctly. Correct message format:
#Ticket Number - Minimum 20 or more Character
like #Android-123 Bug fixed for login issue\n"
exit 1;
fi
Antwort2
Hier würde ich Folgendes tun:
#! /bin/sh -
file="${1?No file specified}"
die() {
printf >&2 '%s\n' "$@"
exit 1
}
awk '
BEGIN {ret = !ok}
/^#Android-[[:digit:]]{3,4}[^[:digit:]].{19}/ {ret = ok}
{exit}
END {exit ret}' < "$file" || die \
'[Message Format] Your message is not formatted correctly. Correct message format:' \
'#Ticket Number - Minimum 20 or more Character' \
'like #Android-123 Bug fixed for login issue'
(Entfernen Sie das ^
, wenn die Ticketnummer nicht am Anfang der Zeile stehen muss).