繁体   English   中英

编写一个 git post-receive 钩子来处理特定的分支

[英]Writing a git post-receive hook to deal with a specific branch

这是我当前在公司服务器中的裸仓库中的钩子: git push origin master这个钩子推送到 Assembla。 我需要的是当有人将更改推送到我们服务器上的那个分支时,只推送一个分支(理想情况下是主分支),而忽略对其他分支的推送。 是否可以从裸仓库中选择分支并仅将该分支推送到 Assembla?

post-receive 钩子从标准输入获取它的参数,格式如下:

<oldrev> <newrev> <refname>

由于这些参数来自标准输入,而不是来自命令行参数,因此您需要使用read而不是$1 $2 $3

post-receive hook 可以一次接收多个分支(例如,如果有人执行git push --all ),因此我们还需要将read包装在while循环中。

一个工作片段看起来像这样:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" = "$branch" ]; then
        # Do something
    fi
done

post-receive hook 在 stdin 上获得的最后一个参数是 ref 被更改的内容,因此我们可以使用它来检查该值是否为“refs/heads/master”。 一些类似于我在 post-receive hook 中使用的 ruby​​:

STDIN.each do |line|
    (old_rev, new_rev, ref_name) = line.split
    if ref_name =~ /master/
         # do your push
    end
end

请注意,它为每个推送的 ref 获取一行,因此如果您推送的不仅仅是 master,它仍然可以工作。

斯特凡的答案并没有为我工作,但这样做的:

#!/bin/bash

echo "determining branch"

if ! [ -t 0 ]; then
  read -a ref
fi

IFS='/' read -ra REF <<< "${ref[2]}"
branch="${REF[2]}"

if [ "master" == "$branch" ]; then
  echo 'master was pushed'
fi

if [ "staging" == "$branch" ]; then
  echo 'staging was pushed'
fi

echo "done"

上述两种解决方案都不适合我。 经过多次调试,结果证明使用“read”命令不起作用——相反,以通常的方式解析命令行参数可以正常工作。

这是我刚刚在 CentOS 6.3 上成功测试的确切更新后挂钩。

#!/bin/bash

echo "determining branch"

branch=`echo $1 | cut -d/ -f3`

if [ "master" == "$branch" ]; then
    echo "master branch selected"
fi

if [ "staging" == "$branch" ]; then
    echo "staging branch selected"
fi

exec git update-server-info

更新:在一个更奇怪的笔记上,预接收钩子通过标准输入获取输入,因此用“读”读取(哇,从没想过我会这么说)。 更新后挂钩对我来说仍然适用于 $1。

@pauljz 的答案对于某些 git 钩子(如pre-push工作正常,但pre-commit无法访问这些变量oldrev newrev refname

所以我创建了这个替代版本,它适用于预提交,或者真的和钩子。 这是一个pre-commit钩子,如果我们不在master分支上,它将运行一个husky脚本。

#!/bin/bash
# git 'commit' does not have access to these variables: oldrev newrev refname
# So get the branch name off the head

branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName
branch=${branchPath##*/}      # Get text behind the last / of the branch path

echo "Head: $branchPath";
echo "Current Branch: $branch";

if [ "master" != "$branch" ]; then

   # If we're NOT on the Master branch, then Do something
   # Original Pre-push script from husky 0.14.3

   command_exists () {
     command -v "$1" >/dev/null 2>&1
   }

   has_hook_script () {
     [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
   }

   cd "frontend" # change to your project directory, if .git is a level higher

   # Check if precommit script is defined, skip if not
   has_hook_script precommit || exit 0

   # Node standard installation
   export PATH="$PATH:/c/Program Files/nodejs"

   # Check that npm exists
   command_exists npm || {
     echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json"
     exit 0
   }

   # Export Git hook params
   export GIT_PARAMS="$*"

   # Run npm script
   echo "husky > npm run -s precommit (node `node -v`)"
   echo

   npm run -s precommit || {
     echo
     echo "husky > pre-commit hook failed (add --no-verify to bypass)"
     exit 1
   }
fi

我希望能帮助某人。 您可以根据需要轻松修改iffi语句之间的任何内容。

我为自己编写了一个 PHP 脚本来完成此功能。

https://github.com/fotuzlab/githubdump-php

将此文件托管在您的服务器上,最好是 repo root 并在 github webhooks 中定义 url。 使用您的分支名称更改第 8 行的“allcommits”,并在第 18 行添加您的代码/函数。

例如

function githubdump($payload_object) {
    // Write your code here.
    exec('git push origin master');
}

简单的做法,在git hook

read refname
echo $refname

简单 - 关于这个伟大的链接 挂钩系统的更多信息

暂无
暂无

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

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