web-dev-qa-db-ja.com

'git pull'コマンドはターミナルから機能しますが、gitリポジトリフックを介したphp Shell_exec()では機能しません

GithubリポジトリにWebhookを作成しました。これは、ライブサーバーのフックURLに投稿して、サーバー上のリポジトリファイルを更新するためのpullコマンドを実行します。

問題は、私が作成したフックファイルが/var/www/site/web/hookfile.phpにあることです(ポストリクエストはそこに送られます。ボディレスポンスも取得しています)

私のリポジトリファイルは/ var/www/git-repo /にあります

githubリポジトリに何かをプッシュしても、git-repoが更新されません。このコマンドは、ターミナルとその動作を使用して実行します。

cd /var/www/git-repo && git pull

しかし、私のphpファイルを通してそれは機能していません

Shell_exec('cd /var/www/git-repo && git pull')
12
Harish Kumar

Shell_exec()は、STDERRではなくSTDOUTのみを報告するため、サイレントに失敗します。

試してみてください:

echo Shell_exec("cd /var/www/git-repo && /full/path/to/bin/git pull 2>&1");

通常はパーミッションエラーであり、php(apache?)を実行するユーザーにパーミッションを追加することで修正できます。

chown -R www-agent:www-agent repository/

ただし、リモートリポジトリへの接続エラー(認証、sshキーなど)の可能性もあります。

11
Dario

まず最初に、phpファイルでサーバーインスタンスに対してテストを実行して、画面にエラーメッセージが出力されるようにします。これは、exec()ファミリーの関数がサイレントに失敗し、STDERRではなくSTDOUTのみを報告するためです。

echo Shell_exec("cd /website/root/htdocs && git checkout . && git status 2>&1");

私の場合、Apacheユーザー用に定義されたバイナリパスがないため、gitコマンドが見つからないというエラーがスローされました。したがって、gitのバイナリへのフルパスを提供する必要があります。手動で見つけるか、シェルで実行することで取得できます。

'which git'

返されました(さらにYOU_FULL_GIT_BINARY_PATH_HEREと呼ばれます):

/usr/local/git/bin/git

Gitコマンドを使用したフルパス(例: '/ usr/local/git/bin/git status'は、gitコマンドを適切に実行するようになりました。

もう1つのことは、Webサーバーのユーザーがリポジトリフォルダー/ファイルの読み取り/書き込みに十分なアクセス許可を持っていることを確認することです。私はApacheユーザーが所有するように設定しました(Centos 6.8の他のリリースはwww:wwwまたはwww-data:www-dataなど):

chown -R Apache:apache YOUR_WEB_OR_REPO_FODLER

新しく追加されたファイルが正しい権限を継承するようにするには、次のコマンドを実行します。

chmod -R g+s YOUR_WEB_OR_REPO_FODLER

上記により、スクリプトでコマンドを実行できるようになります。 git passwordは克服されませんが、YOUR_WEB_OR_REPO_FODLER/.git/configファイルで設定されたgitユーザーに対して「gitpull」コマンドを使用するように求められます。リポジトリ内で以下のコマンドを実行します。

git config credential.helper store

command はパスワードの入力を求め、ローカルに保存できるようにします。保存されたパスワードは暗号化されず、ファイルシステムによってのみ保護されることに注意してください。 /root/.git-credentialsにあります。これにより、パスワードの入力を求めずに「gitpull」を実行できます。

Git user(repoの.git/config gitで定義)パスワードを少なくとも1回手動で入力する必要があるため、テストVPSをオンデマンドでデプロイする完全に自動化された継続的インテグレーション環境には理想的ではありません。

私の環境は常にリモートのオリジン/マスターコピーからのコードで実行する必要があるため、私も実行しています

/YOU_FULL_GIT_BINARY_PATH_HERE/git checkout .

'git pull'を呼び出してローカルの変更が永久に失われるようにする前に、代わりに次を使用してハードリセットを実行します。

/YOU_FULL_GIT_BINARY_PATH_HERE/git fetch Origin
/YOU_FULL_GIT_BINARY_PATH_HERE/git reset --hard Origin/master
2
webcoder.eu