【问题标题】:How to create a git post-receive hook which sends an email if a particular file has been modified?如果特定文件已被修改,如何创建一个 git post-receive 钩子发送电子邮件?
【发布时间】:2013-11-07 16:04:38
【问题描述】:

我想将以下行为添加到由 gitolite 管理的 git 存储库中。在推送到 master 的东西上(可以忽略其他分支),我想检测一个特定文件是否在其中一个提交中被更改,如果是,则向指定地址发送电子邮件。电子邮件内容每次都可以相同。可以通过执行脚本或 bash 命令发送电子邮件,假设必要的可执行文件可用。

如何使用 git post-receive 钩子来完成这项工作?


背景:对某个文件的更改需要内部手动过程来处理代码中不受控制的内容。我希望通过电子邮件提醒您完成该手动过程。

【问题讨论】:

    标签: git email version-control git-post-receive


    【解决方案1】:

    我通过添加如下内容作为接收后挂钩实现了我的目标:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my ($from, $to, $branch) = split /\s+/, $i;
    my ($project) = $pwd =~ /\/([^\/]+)\.git$/;
    my $name_of_file_i_care_about = "SomeFileName.txt"
    
    if ($project eq 'my_project') {
    
      my $contains_change_to_file_i_care_about = system( "git diff --name-only $from $to | grep --quiet $name_of_file_i_care_about" );
    
      if ($contains_change_to_file_i_care_about == 0) {
        system("mail --to 'someone\@somewhere.com' --subject 'Hey, that file you care about has changed.'");
      }
    }
    
    exit 0;
    

    请注意,这取决于某些外部命令:grepmail。我主要复制和破解了我们现有的接收后挂钩,这可能取决于我们的特定配置,也可能不取决于我们的特定配置。如果有更好的方法,我会全力以赴。

    【讨论】:

    • 您可以使用git diff <flags> <oldrev> <newrev> -- <path> ... 将差异限制为您关心的路径。在这种情况下,只需在此处添加 -- $name_of_file_i_care_about 并将管道拖放到 grep。
    • 谢谢@torek。 IIRC 的权衡是在更快的git diff 和对正在移动的文件更健壮之间进行权衡,例如到一个新目录。对我来说,额外的稳健性是值得的。
    • 如果文件被重命名,您将进入一个痛苦的世界,因为下次有人推送时,它会以新名称从您的脚本中溜走。您可能还想检查文件在推送后是否仍然存在,如果不存在则发出响亮的爆炸声。
    • @TomAnderson:好点。您知道是否可以检查裸存储库中是否存在文件?
    • 如果您执行git log --oneline $from..$to SomeFileName.txt,如果有更改,则应该打印一些行,如果没有更改,则不打印任何内容,然后失败(在 stderr 上呻吟并以非零状态退出) 如果文件不存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2014-05-13
    • 2014-10-28
    相关资源
    最近更新 更多