繁体   English   中英

Perl —退出1时,commit-msg挂钩不会停止提交

[英]Perl — commit-msg hook doesn't stop the commit when exiting 1

内容:

我正在使用一些git-hooks自动在Perl脚本上应用某些格式设置选项。 在预提交的钩子上,我使用perltidy清理并重新格式化了脚本。 我想检查用户在提交消息上放置了什么内容,如果它为空或等于“中止”,我们要阻止提交并撤消格式修改。

问题:

我删除了git hook的.sample扩展名,并使用chmod u+x .git/hooks/commit-msg使它可执行,但是当我的脚本exit 1 ,提交并没有像应该的那样停止。

提交-MSG

这个钩子由git-commit [1]和git-merge [1]调用,可以使用--no-verify选项绕过。 它只有一个参数,即保存建议的提交日志消息的文件的名称。 以非零状态退出会导致命令中止。

来源: https : //git-scm.com/docs/githooks#_commit_msg

#!/usr/bin/perl -w

use strict;
use warnings;

# Get the path to the files in which we have the commit message
my $commit_file = $ARGV[0];

# Read the file and extract the commit message (lines which don't start with #) 
my @commit_msg;
open(my $fh, "<", "$commit_file");
while (my $line = <$fh>) {
    if (substr($line, 0, 1) ne "#") {
        push(@commit_msg, $line);
    }
}

# Check the message isn't empty or we don't have a "abort" line
my $boolean = 0;
foreach my $line (@commit_msg) {
    if ($line ne "abort" && $line ne "") {
        $boolean = 1;
    }
}

if ($boolean == 0) {
    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
}

该脚本是可执行的并且有效! 如果在提交某些内容时输入“ abort”,它会显示“我们不应该提交所做的修改”,但提交时将放弃出口1 ...

希望有人能够提供帮助! 我是git-hook的新手,找不到解决方案。 也许我在Stackoverflow上错过了一些东西,但是我没有找到回答此问题的帖子。

最好,

安托万

编辑:我不承诺使用:-- --no-verify

当我第一次安装您的钩子时,我无法使其执行任何操作 ,但这是因为该钩子具有太多的底片。 您的语言老师提倡避免双重否定的警告也会在编写软件时帮助您。 钩子尝试通过负向测试来确定行是否良好,以寻找有效条件;如果是,则将$boolean设置$boolean 1,然后仅在$boolean为0时exit 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)使用shift@ARGV提取参数。

(3)始终 始终检查open的返回值。 请注意,错误消息(如果确实失败)包含具有错误( $0 )的程序的名称,试图执行的操作( "open $commit_file" )和错误( $! )。 养成这个习惯。 有一天,它将为您节省很多挫败感。

(4)不是将线复制到数组中,而是将它们全部连接到一个标量中。 使用while (<$fh>) { ... }查看$_每一行,这是Perl的惯用语,会使代码混乱。

(5) next if /^#/;则跳过注释行变得很简单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自然读取的方式将$valid_commit_msg用作布尔值。

if ($valid_commit_msg) { ... }

if ($valid_commit_msg == 0) { ... }更可取,因为0值是一个错误的值,重复良好的值是多余的,并且结尾处的值很容易被忽略。

我认为您脚本中的逻辑是相反的,即单词abort不会导致退出代码1。

我认为以下应该起作用:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

my($commit_msg_file) = @ARGV
    or die "usage: $0 <commit message file>\n";

open(my $fh, '<', $commit_msg_file);
my $do_commit;
while (<$fh>) {
    # skip comment or empty lines
    next if /^#/ || /^\s*$/;

    # check for the word "abort" on its own line
    last if (/^abort$/);

    # at least one non-empty non-comment line detected
    $do_commit++;
    last;
}
close($fh);

if ($do_commit) {
    print "We should commit the modifications\n";
    exit 0; # Don't prevent commit
}

print "We shouldn't commit the modifications\n";
exit 1; # Prevent commit

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM