Solved: Running git pull from a php script causing an error?

I wanted to improve my Git workflow, so I went about using GitHub’s Service Hooks to set up a web hook to my development server. The idea being that I would have GitHub ping my server every time I or anyone else pushes to the master GitHub repository.

The idea was pretty simple. I would have a php file located on my development server with following command.

<?php shell_exec('git pull'); ?>

However, I quickly ran into the following permission error.

error: cannot open .git/FETCH_HEAD: Permission denied

The reason being was that my server’s Apache user doesn’t and shouldn’t have access to the root. However, to run git pull, it was trying to access the host keys, which are stored in the ~/.ssh/known_hosts file. As you can see, these files are located in the root.

So I was scratching my head for a solution when I came across this terrific tutorial, Github playground servers and auto pull from master, posted by Konstantin Kovshenin. Konstantin proposed a simple, but brilliant, solution of using the GitHub service hook to ping a local php file that would signal a server cron job to handle the git pull. If you are trying to do the same thing, and experienced the above error, follow the Konstantin’s tutorial and it should work for you.

Final notes: having a development server automatically pull from the Git repository is very useful, however it is not a good idea for production servers. It is more secure and more controlled to manually update your production servers git repository from the command line.

By Jonathan Whiting

I enjoy sharing what I am learning and hopefully it's of interest and help to you. I live in Canada with my wife. Follow me on Twitter.

2 replies on “Solved: Running git pull from a php script causing an error?”

if you just want to clone from a git repo (i have edited this but you get the idea)
* This function handles the pull / init / clone of a git repo
* @param $git_url
* Example of git clone url git://
* @return bool true
public static function pullOrCloneRepo($git_url) {
if (!isset($git_url)) {
return false;
// validate contains git://
if (strpos($git_url, ‘git://’) !== FALSE) {
// create a directory and change permissions
$uri = ‘public://somedir’
//check the dir
$file_path = drupal_realpath($uri); // change this if not in drupal
if (isset($file_path)) {
$first_dir = getcwd();
// change dir to the new path
$new_dir = chdir($file_path);
// Git init
$git_init = shell_exec(‘git init’);
// Git clone
$git_clone = shell_exec(‘git clone ‘. $git_url);
// Git pull
$git_pull = shell_exec(‘git pull’);
// change dir back
$change_dir_back = chdir($first_dir);
return true;
else {
return false;

Leave a Reply

Your email address will not be published.