121

Is there any way to set up git such that it listens for updates from a remote repo and will pull whenever something changes? The use case is I want to deploy a web app using git (so I get version control of the deployed application) but want to put the "central" git repo on Github rather than on the web server (Github's interface is just soooo nice).

Has anyone gotten this working? How does Heroku do it? My Google-fu is failing to give me any relevant results.

6 Answers 6

65

Git has "hooks", actions that can be executed after other actions. What you seem to be looking for is "post-receive hook". In the github admin, you can set up a post-receive url that will be hit (with a payload containing data about what was just pushed) everytime somebody pushes to your repo.

For what it's worth, I don't think auto-pull is a good idea -- what if something wrong was pushed to your branch ? I'd use a tool like capistrano (or an equivalent) for such things.

3
  • 19
    My planned use case was to have a separate repo/branch for the dev "testing and messing around" stage, and have a special "push to production" repo that I push to only once I'm sure everything works. I'm basically using Git to do with rsync could do, except it keeps a log of all the versions that get deployed, and I'd easily be able to roll back to a previous version. The advantage over something more hardcore like capistrano is I wouldn't have to learn a whole new tool for what is (as of now) a really small project.
    – Li Haoyi
    Commented Apr 2, 2012 at 15:18
  • webhook authentication adds extra safety issues and complexity, so pull-based solutions still have their advantages. Release version control can be done with tags to avoid accidental deployment.
    – lz96
    Commented Jul 6, 2020 at 3:06
  • i think it's good for development with a group.
    – DoctorHe
    Commented Feb 22, 2022 at 8:40
28

On unix-likes you can create cron job that calls "git pull" (every day or every week or whatever) on your machine. On windows you could use task scheduler or "AT" command to do the same thing.

9
  • 7
    Not a proper way of using Git.
    – deepdive
    Commented May 27, 2015 at 2:30
  • 37
    @deepdive Why not? Imagine you have a little Rasperry Pi in your home and no static IP available. What other option have you got then running a cron or runwhen job?
    – kaiser
    Commented Jan 3, 2016 at 3:38
  • 6
    Its not a good idea. He wants the changes to be applied immediately after pushing. Commented Jul 29, 2016 at 6:02
  • 17
    The OP is specifically asking for a method that listens for updates from a remote repo and will pull whenever something changes. This solution would just pull from the repository every so often, so in order for it to be effective the interval would have to be very short, leading to a great many of redundant pull requests.
    – Boaz
    Commented Oct 26, 2016 at 9:18
  • 7
    A quick way to do this without changing cron tab: while true; do git pull; sleep 10; done. This will do a git pull every 10 seconds...
    – JakeD
    Commented Feb 7, 2018 at 16:41
4

There are continuous integrations programs like Jenkins or Bamboo, which can detect commits and trigger operations like build, test, package and deploy. They do what you want, but they are heavy with dependencies, hard to configure and in the end they may use periodical check against git repository, which would have same effect like calling git pull by cron every minute.

2

As some have noticed after trying this, if you use php exec(), it turns out that solving for permissions is not that simple.

The user that will execute the command might not be your own, but www-data or apache.

If you have root/sudo access, I recommend you read this Jonathan's blog post

When you aren't allowed/can't solve permissions

My solution was a bit creative. I noticed I could create a script under my username with a loop and git pull would work fine. But that, as pointed out by others, bring the question of running a lot of useless git pull every, say, 60 seconds.

So here the steps to a more delicate solution using webhooks:

  • deploy key: Go to your server and type: ssh-keygen -t rsa -b 4096 -C "deploy" to generate a new deploy key, no need write-permissions (read-only is safer). Copy the public key to your github repository settings, under "deploy key".
  • Webhook: Go to your repository settings and create a webhook. Lets assume the payload address is http://example.com/gitpull.php
  • Payload: create a php file with this code example bellow in it. The purpose of the payload is not to git pull but to warn the following script that a pull is necessary. Here the simple code:

gitpull.php:

<?php

/* Deploy (C) by DrBeco 2021-06-08 */

echo("<br />\n");
chdir('/home/user/www/example.com/repository'); 
touch(GITPULLMASTER);
?>
  • Script: create a script in your preferred folder, say, /home/user/gitpull.sh with the following code:

gitpull.sh

#!/bin/bash

cd /home/user/www/example.com/repository
while true ; do
      if [[ -f GITPULLMASTER ]] ; then
            git pull > gitpull.log 2>&1
            mv GITPULLMASTER GITPULLMASTER.`date +"%Y%m%d%H%M%S"`
      fi
      sleep 10
done
  • Detach: the last step is to run the script in detached mode, so you can log out and keep the script running in background.

There are 2 ways of doing that, the first is simpler and don't need screen software installed:

  • disown:

    • run ./gitpull.sh & to put it in background
    • then type disown -h %1 to detach and you can log out
  • screen:

    • run screen
    • run ./gitpull.sh
    • type control+a d to detach and you can log out

Conclusion

This solution is simple and you avoid messing with keys, passwords, permissions, sudo, root, etc., and also you prevent the script to flood your server with useless git pulls.

The way it works is that it checks if the file GITPULLMASTER exists; if not, back to sleep. Only if it exists, then do a git pull.

You can change the line:

mv GITPULLMASTER GITPULLMASTER.date +"%Y%m%d%H%M%S"`

to

rm GITPULLMASTER

if you prefer a cleaner directory. But I find it useful for debug to let the pull date registered (and untracked).

0
0

For our on-premises Windows test servers, we use Windows Task Scheduler tasks, set to run every 3 minutes, pulling from Bitbucket Cloud to repositories on those servers. While not instantaneous, it meets our needs, and has proven to be reliable.

-1

I know this question is a bit old, but you can use the windows log and git to autopull your project using a webhook and php (assuming your project involves a webserver. See my gist here : https://gist.github.com/upggr/a6d92e2808e9628ebe0d01fd93569f4a

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.