web-dev-qa-db-ja.com

特定のブランチに対処するためのgit post-receiveフックの作成

これは、会社のサーバーにある裸のレポでの私の現在のフックです:git Push Origin masterこのフックは、Assemblaにプッシュします。私が必要とするのは、誰かが私たちのサーバー上のそのブランチに変更をプッシュし、他のブランチへのプッシュを無視するときに、1つのブランチ(理想的にはマスター)のみをプッシュすることです。ベアリポジトリからブランチを選択し、そのブランチのみをAssemblaにプッシュすることは可能ですか?

102
Jorge Guberte

Post-receiveフックは、<oldrev> <newrev> <refname>の形式で標準入力から引数を取得します。これらの引数はコマンドライン引数からではなく、stdinから取得されるため、$1 $2 $3の代わりにreadを使用する必要があります。

Post-receiveフックは一度に複数のブランチを受信できます(たとえば、誰かがgit Push --allを実行する場合)。したがって、readwhileループにラップする必要もあります。

動作するスニペットは次のようになります。

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

Post-receiveフックがstdinで取得する最後のパラメーターは、refが変更されたものなので、その値を使用して、その値が「refs/heads/master」であったかどうかを確認できます。少しのRubyは、受信後フックで使用するものに似ています。

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

プッシュされたrefごとに行を取得することに注意してください。したがって、マスター以外のものをプッシュした場合でも機能します。

8
ebneter

ステファンの答えは私にとってはうまくいきませんでしたが、 this はうまくいきました:

#!/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"
6
Dean Rather

上記の解決策のどちらも私にとってはうまくいきませんでした。多くのデバッグの後、「読み取り」コマンドを使用しても機能しないことがわかりました。代わりに、通常の方法でコマンドライン引数を解析すると問題なく動作します。

これが、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

更新:さらに奇妙なことに、pre-receiveフックはstdinを介して入力を受け取るため、 'read'で読み取ります(うわー、私はそれを言うとは思わなかった)。更新後のフックは、まだ1ドルで機能します。

3
razvan

@pauljzからの答えは、pre-Push、ただしpre-commitはこれらの変数にアクセスできませんoldrev newrev refname

そこで、私はこの代替バージョンを作成しました。これは、プリコミット、または実際にフックに使用できます。これは pre-commitフックがhuskyブランチ上にない場合にmasterスクリプトを実行します。

#!/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ステートメントの間にあるものであれば、必要に応じて簡単に変更できます。

1
TetraDev

私はこの機能を実行するためにPHPスクリプトを書きました。

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

このファイルをサーバー(できればリポジトリのルート)でホストし、github webhookでURLを定義します。 8行目の「allcommits」をブランチ名で変更し、18行目にコード/関数を追加します。

例えば.

function githubdump($payload_object) {
    // Write your code here.
    exec('git Push Origin master');
}
0
fotuzlab

git hook書き込みのシンプルなアプローチ

read refname
echo $refname

シンプル-このすばらしいリンクの詳細 フックシステム

0
Haris Krajina