16

I have create a webhook in my github repository which post on the hook url on my live server to run pull command for update my repo files on the server.

The problem is the hook file which i have created is in the /var/www/site/web/hookfile.php (the post request is going there. i am getting the body response also)

and my repo files are in /var/www/git-repo/

its not updating the git-repo when i push anything to my github repository. I run this command using terminal and its working.

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

But through my php file its not working

shell_exec('cd /var/www/git-repo && git pull')
Harish Kumar
  • 927
  • 3
  • 20
  • 46

2 Answers2

20

shell_exec() fail silently because only report STDOUT and not STDERR.

Try with:

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

Normally is a permission error, and could be fixed adding permission to the user that execute php (apache?)

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

But could be also a connection error to the remote repository (authentication, ssh-keys, ...).

Dario
  • 3,905
  • 2
  • 13
  • 27
  • full path means where my /.git is located ? @dario – Harish Kumar Jun 10 '16 at 16:44
  • 1
    yes @harish-kumar. you can execute `which git` in a terminal to get it – Dario Jun 10 '16 at 16:46
  • 2
    getting this error: cannot open .git/FETCH_HEAD: Permission denied – Harish Kumar Jun 10 '16 at 16:48
  • so is a permission error, the user that exec php can't read the repository. you should manually fix permissions with chmod / chown. Example: `chown -R www-data:www-data /var/www/git-repo` – Dario Jun 10 '16 at 16:53
  • changed the permission too, added ssh key also but not worked. i am trying to clone frommy php file also, its not cloning also – Harish Kumar Jun 10 '16 at 17:30
  • same : Permission denied, is that possible if its parent directory www dont have the write permission that is why its not allowing. I can not change the /www permission with current user – Harish Kumar Jun 12 '16 at 07:42
  • @Dario I followed you mentioned procedure but I'm getting this error 'Could not create directory '/var/www/.ssh'. Host key verification failed. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.' how to fix it? – Kishore Jan 06 '20 at 12:30
5

First of all in your php file run a test against your server instance to get any error messages output on screen because the exec() family of functions simply fail silently and only report STDOUT and not STDERR:

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

In my case this threw an error that it could not find git command due to lack of binary path defined for apache user. Therefore, a full path needs to be provided to git's binary. It can be obtained by finding it manually or running in shell:

'which git'

It returned (further called YOU_FULL_GIT_BINARY_PATH_HERE):

/usr/local/git/bin/git

A full path with git command e.g. '/usr/local/git/bin/git status' now runs git commands nicely.

Another thing is to ensure your web server user has enough permissions to read/write to your repo folder/files. I have set mine to be owned by the apache user (Centos 6.8; other releases might be www:www or www-data:www-data etc.):

chown -R apache:apache YOUR_WEB_OR_REPO_FOLDER

In order to ensure any newly added files inherit correct permissions run:

chmod -R g+s YOUR_WEB_OR_REPO_FOLDER

The above should get your script to run commands now. Though it doesn't overcome git password prompt to use 'git pull' command for a git user set in YOUR_WEB_OR_REPO_FOLDER/.git/config file. Running below command inside repo:

git config credential.helper store

command will prompt for password and let you store it locally. Please note your stored password will be unencrypted and protected only by file system e.g. in /root/.git-credentials. This will allow to run 'git pull' without prompting for password.

It's not ideal for my fully automated continuous integration environment deploying test VPS on demand as it requires to manually enter git user (defined in repo's .git/config git) password at least once.

Since my environment should always run on code from remote's origin/master copy I am also running

/YOU_FULL_GIT_BINARY_PATH_HERE/git checkout .

before invoking 'git pull' to ensure any local changes are lost forever alternatively do a hard reset instead using:

/YOU_FULL_GIT_BINARY_PATH_HERE/git fetch origin
/YOU_FULL_GIT_BINARY_PATH_HERE/git reset --hard origin/master
Laurel
  • 5,965
  • 14
  • 31
  • 57
webcoder.co.uk
  • 341
  • 3
  • 5