Когда я впервые установил ваш хук, я не смог заставить его совершить что-нибудь , но это потому, что у хука слишком много негативов.Предупреждения вашего преподавателя языка, чтобы избежать двойных негативов, помогут вам при написании программного обеспечения.Хук пытается найти допустимое условие, проверяя в отрицательном смысле, если строка выглядит хорошо, установите $boolean
в 1, если это так, но тогда exit 0
(указывает на успех), только если $boolean
было 0.
Неописанное имя $boolean
, вероятно, частично ответственно.Возможно, вы потеряли отслеживание вашего предполагаемого значения между его настройкой и тем статусом выхода, который вы хотели создать.Кроме того, ваше намерение за логикой не будет выполнено, пока последняя строка сообщения фиксации верна.
Приведенный ниже код работает так, как вам нужно с git 2.17.1.
#! /usr/bin/perl -w
use strict;
use warnings;
die "Usage: $0 commit-log-message\n" unless @ARGV == 1; # (1)
# Get the path to the files in which we have the commit message
my $commit_file = shift; # (2)
# Read the file and extract the commit message (lines which don't start with #)
my $commit_msg = "";
open my $fh, "<", $commit_file or die "$0: open $commit_file: $!"; # (3)
while (<$fh>) { # (4)
next if /^#/; # (5)
$commit_msg .= $_;
}
# Check the message isn't empty or we don't have an "abort" line
my $valid_commit_msg = $commit_msg ne "" && $commit_msg !~ /^abort$/m; # (6)
if ($valid_commit_msg) { # (7)
print "We should commit the modifications\n";
exit 0; # Don't prevent commit
}
else {
print "We shouldn't commit the modifications\n";
exit 1; # Prevent commit
}
(1) Да, предполагается, что git предоставляет имя файла с сообщением журнала, но проверяет его работоспособность в случае, если код скопирован или иным образом установлен в неправильном хуке.
(2) Соберите аргумент из @ARGV
с shift
.
(3) Всегда, всегда , всегда проверьте возвращаемое значение с open
.Обратите внимание, что сообщение об ошибке, если оно терпит неудачу, содержит имя программы, в которой произошла ошибка ($0
), что она пыталась сделать ("open $commit_file"
) и ошибка ($!
).Развивайте эту привычку.Это избавит вас от многих неприятностей в один прекрасный день.
(4) Вместо того, чтобы копировать строки в массив, объедините их все в один скаляр.Используйте while (<$fh>) { ... }
, чтобы увидеть каждую строку в $_
, что является более идиоматическим Perl и обезвреживает ваш код.
(5) Пропуск строк комментариев становится простым next if /^#/;
.
(6) Скажите, что вы имеете в виду.Вместо механизма ($boolean
) назовите свое намерение.Вы хотите знать, что сообщение коммита является действительным, прежде чем пропустить его.Допустимое сообщение фиксации должно соответствовать двум условиям:
- Сообщение фиксации не является пустым.
- Сообщение фиксации не содержит строки, единственное содержимое которой равно
abort
.
В Perl это
my $valid_commit_msg = $commit_msg ne "" && $commit_msg !~ /^abort$/m;
Пара замечаний:
- Оператор
!~
инвертирует смысл соответствия регулярному выражению, т.е. , $commit_msg
должен не содержать abort
. - Переключатель
/m
в конце шаблона предназначен для многострочного режима.При этом якоря ^
и $
совпадают в начале и конце строк в пределах цели, а не только с левыми и самыми правыми символами.
(7) Использование$valid_commit_msg
как логическое значение, которое читается естественным образом.
if ($valid_commit_msg) { ... }
предпочтительнее if ($valid_commit_msg == 0) { ... }
, потому что значение 0 было неправильным, повторение правильного значения избыточно, а значение висит наконец легко не заметить.