Git Sync Remote Branch Automatically by Webhook

How to make your local repository always sync with GitHub repository? The answer is webhook.

When the repo received a push event, GitHub will send a POST request to the webhook URL with details of any subscribed events. What we need to do is to implement a webhook (on local side) which performs git pull to keep sync with remote.

Simplest GitHub Webhook Implementation

What's a webhook?

Webhooks allow you to build or set up integrations, such as GitHub Apps or OAuth Apps, which subscribe to certain events on When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination

Here we implement a simplest webhook which handles push event from GitHub. No secret, no payload parsing, just git pull --ff-only origin master when receiving the push event. More complicated webhook development can refer to here.


import git
import logging
from flask import Flask


app = Flask('gitwebhook')

def pull():
    repo = git.Repo('/home/local/repo/folder')
    repo.git.pull('--ff-only', 'origin', 'master')

@app.route('/push',methods = ['POST'])
def handle_push():"Received push event")
    except Exception as ex:
        return str(ex), 500

    return 'Success'

if __name__ == '__main__':'', port=5000)

The above code is pretty clean and self-explained. We use Flask as the webserver and leverage gitpython to perform git operations.

Then we can serve the webhook on your local machine which can access the local repo /home/local/repo/folder. Assume the server is running at

Configure Webhook on GitHub

Goto repo Settings -> Webhooks -> Add Webhook:

Configure GitHub Webhook


Let's check the delivery result by clicking the webhooks detail, Recent Deliveries:

GitHub Webhook Deliveries Results

The webhook return success if it pulls remote master by fast-forward, otherwise, an exception will be thrown and return HTTP 500.