Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
跳过先前已处理的post接收挂钩中的Git修订的处理_Git_Git Post Receive - Fatal编程技术网

跳过先前已处理的post接收挂钩中的Git修订的处理

跳过先前已处理的post接收挂钩中的Git修订的处理,git,git-post-receive,Git,Git Post Receive,我有一个git post receive钩子,它提取在“git推送”过程中添加的所有修订,并对每个修订进行一些处理(例如发送通知电子邮件)。这非常有效,除非在合并时;e、 g: 我在branch1上进行了一些提交,然后推动branch1。post接收钩子正确处理提交 我将branch1合并到branch2,然后推动branch2。post-receive钩子第二次处理所有合并的提交 我怎样才能避免这种情况?下面是post-receive钩子的开头,在这里我提取了应该处理的提交(在$commits

我有一个git post receive钩子,它提取在“git推送”过程中添加的所有修订,并对每个修订进行一些处理(例如发送通知电子邮件)。这非常有效,除非在合并时;e、 g:

  • 我在branch1上进行了一些提交,然后推动branch1。post接收钩子正确处理提交
  • 我将branch1合并到branch2,然后推动branch2。post-receive钩子第二次处理所有合并的提交
  • 我怎样才能避免这种情况?下面是post-receive钩子的开头,在这里我提取了应该处理的提交(在$commits末尾保存了要处理的提交列表)


    我们要做的是将先前处理的提交的散列保存在文本文件中。每次钩子运行时,它都会在该文件中检查给定的提交是否已被处理。如果它尚未处理该提交,请处理它,然后将该提交记录到文件中


    这不是非常可伸缩的,因为文本文件只会随着更多提交添加到存储库而增长,并且检查给定提交的时间也会增长。

    我们通过让post receive钩子在遇到合并提交(具有两个或多个父级的提交)时停止处理来实现这一点。这需要在推动合并时遵守一些规则,以确保不会抛出其他“真正的”提交。规则是在合并之前总是推送,然后分别推送合并。

    看看
    $(前缀)/share/git core/contrib/hooks/post receive email
    ,这正是(我认为)你想要的。基本上,它对每个ref使用
    git
    来查找所有分支的名称,然后排除从某个分支(更新的分支除外)可以访问的每个提交:

    if [ "$change_type" = create ]
    then
        # Show all revisions exclusive to this (new) branch.
        revspec=$newrev
    else
        # Branch update; show revisions not part of $oldrev.
        revspec=$oldrev..$newrev
    fi
    
    other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
         grep -F -v $refname)
    git rev-parse --not $other_branches | git rev-list --pretty --stdin $revspec
    

    (我在这里简化了它,希望在我的剪切粘贴工作中不会损坏任何东西。这里的输入是:
    $change\u type
    create
    ,如果
    $oldrev
    都是零,否则它是
    update
    $oldrev
    是最近从stdin读取的行中的旧版本SHA1;
    $newrev
    是新版本HA1;
    $refname
    是全名,例如,
    refs/heads/topic

    我在一个post接收钩子中完全实现了这一点。它只通知trac自上次获取以来的新提交,而不重复,无论新提交是同时推送到单个分支还是多个分支。此方法在git目录中保留一个名为
    trac\u HEAD
    的文件以供tra使用正在检查已处理的提交

    建议在启用挂钩之前,在
    .git
    目录中运行
    cat refs/heads/*>TRAC HEAD

    !/bin/sh
    #
    #仅读取并通知trac尚未处理的新提交。
    #
    #“接收后”脚本在接收包接受包后运行
    #并且存储库已经更新。它是通过参数传入的
    #格式中的stdin
    #    
    #例如:
    #aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814参考/页眉/母版
    #
    TRAC_PATH=“/PATH/to/TRAC/env”
    #读取标准输入
    在读取oldrev newrev refname;时
    echo“处理分支:$refname”
    #从TRAC_HEAD读取每个分支的最新修订
    除外条款=$(cat TRAC|U HEAD | uniq | sed-e's/^/^/'-e's//^/g'| xargs echo)
    回显“排除列表:$Exclutions”
    git版本列表——在读取版本时撤销$newrev$排除项
    trac admin$trac_路径变更集已添加“(默认)’$rev
    echo“已处理:$rev”
    完成
    #将此分支的最新版本添加到排除文件中
    echo$newrev>>跟踪头
    完成
    #更新TRAC_头文件
    cat参考/头部/*>TRAC\u头部
    
    改进此方法的一个方法是定期修剪文件,与您关于合并分支频率的政策保持一致。感谢您的回答。我将使用上面torek的解决方案,但您的回答也可以避免我在这里提到的剩余角落案例。不过,在文本文件中跟踪提交更为有效这比我现在要介绍的要复杂得多。多亏了这一点,它正好满足了我的需要。使用此代码,剩下的情况是,当您进行提交时,将其合并到另一个分支中,然后将两个更改同时推送到一起。在这种情况下,每个分支中的修订都可以从另一个分支访问,因此不会进行处理完全可以。但是,这对我们来说现在是可以接受的,因为这是一个相对少见的情况。有趣!如果你在pre-receive钩子中而不是post-receive中这样做,它可能会扫描这两次,因为两个ref都不会被更新。也许如果你在update钩子中这样做,它会只扫描一次?(显然,我自己没有试过。)
    if [ "$change_type" = create ]
    then
        # Show all revisions exclusive to this (new) branch.
        revspec=$newrev
    else
        # Branch update; show revisions not part of $oldrev.
        revspec=$oldrev..$newrev
    fi
    
    other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
         grep -F -v $refname)
    git rev-parse --not $other_branches | git rev-list --pretty --stdin $revspec