1 git-mirror - Sync your git repositories
2 =======================================
7 git-mirror_ is a tool to keep multiple git repositories of the same project in
8 sync. Whenever something is pushed to any repository, the commits will
9 immediately be forwarded to all the others. The tool assumes to run on a server
10 hosting one of these repositories - so there has to be at least one you can
11 control. A typical use-case would be your own gitolite_ installation, that you
12 want to keep in sync with GitHub_.
14 .. _git-mirror: https://www.ralfj.de/projects/git-mirror
15 .. _gitolite: http://gitolite.com/gitolite/index.html
16 .. _GitHub: https://github.com/
21 This describes how you set up git-mirror on a server running gitolite. For other
22 git hosting software, please consult the respective documentation on adding git
23 hooks. I will assume that gitolite is installed to ``/home/git/gitolite``, that
24 the repositories are sitting in ``/home/git/repositories``, and that git-mirror
25 has been cloned to ``/home/git/git-mirror``.
27 First of all, you need to create a file called ``git-mirror.conf`` in the
28 ``git-mirror`` directory. For now, it only needs to contain a single line::
30 mail-sender = git@example.com
32 We will also need to add hooks to the git repositories you want to sync. The
33 easiest way to manage these hooks is to put them into your ``gitolite-admin``
34 repository, so enable the following line in ``/home/git/.gitolite.rc``::
36 LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
38 Make sure you read the `security note
39 <http://gitolite.com/gitolite/non-core.html#pushcode>`_ concerning this
42 Now add a file called ``local/hooks/repo-specific/git-mirror`` to your
43 ``gitolite-admin`` repository, make ii executable, and give it the following
47 exec ~/git-mirror/githook.py
49 For every repository you want to be synced, you can enable the hook by adding
50 the following line to its configuration in ``conf/gitolite.conf``::
52 option hook.post-receive = git-mirror
54 (If you need multiple hooks here, you can separate them by spaces.)
56 Finally, you need to tell git-mirror where to sync incoming changes to this
57 repository to. Add a block like the following to ``git-mirror.conf``::
61 local = /home/git/repositories/repo-name.git
63 mirror-a = git@server2.example.com:repo-name.git
64 mirror-b = git@server2.example.org:the-repo.git
66 Here, ``local`` has to be set to the path where the repository is stored
67 locally. ``deploy-key`` is the name of the SSH key used for pushing the changes
68 to other repositories. ``owner`` is the e-mail-address that error messages
69 occurring during synchronization are sent to. And finally, the URLs to push to
70 are given by ``mirror-<something>``. If these other servers also run gitolite
71 and have a symmetric setup, then no matter where a change is pushed, git-mirror
72 will forward it to all the other repositories.
77 This explains how to configure a GitHub repository that should be part of a
78 synchronized set. I will assume that one of the copies of the repository lives
79 on a gitolite server you control.
81 Since you cannot install a normal git hook on GitHub, syncing changes that are
82 sent to GitHub has to be done with a webhook. First of all, you will have to
83 configure your webserver to run ``webhook.py`` as CGI script. Consult the
84 webserver documentation for more details.
86 Secondly, ``webhook.py`` needs to be able to find the main git-mirror scripts,
87 and it needs to be able to execute them as the ``git`` user. For the first
88 point, open ``webhook.py`` and change ``webhook_core`` to point to the file
89 ``webhook-core.py`` in your git-mirror clone. If your installation matches the
90 paths I used above, that should already be the case. For the second point,
91 ``webhook.py`` is using ``sudo`` to elevate its privileges. You need to tell
92 ``sudo`` that this is all right, by creating a file
93 ``/etc/sudoers.d/git-mirror`` with content::
95 www-data ALL=(git) NOPASSWD: /home/git/git-mirror/webhook-core.py
97 Now, if you visit ``https://example.com/git-mirror/webhook.py`` (replace with
98 your URL), the script should run and tell you ``Repository missing or not
101 The next step is to add this as a webhook to the GitHub repository you want to
102 sync with, to create a fresh SSH key and configure it as deployment key for the
103 repository, and to configure git-mirror accordingly. For additional security,
104 one shouldalso configure a shared HMAC secret, such that the webhook can verify
105 that the data indeed comes from GitHub.
107 To make your job easier, there is a script ``github-add-hooks.py`` that can do
108 all this for you. It assumes that the repository exists on the GitHub side, but
109 has not yet been configure for git-mirror, neither locally nor remotely.
111 To give the script access to your repositories, you need to create an access
112 token for it. Go to "Personal Access Tokens" in your GitHub configuration, and
113 create a new token with the permissions ``admin:repo_hook`` and ``public_repo``.
114 Add the token and the webhook URL to the top part of ``git-mirror.conf`` (right
115 below ``mail-sender``)::
117 github-token = pastethetokenhere
118 webhook-url = https://example.com/git-mirror/webhook.py
120 Now you can call the automatic setup script as follows::
122 ./github-add-hooks.py -o UserName -e email@ddress.com -l ~/repositories/repo-name.git/ -n github-repo-name
124 Notice that the username is case-sensitive! This will do all the setup on the
125 GitHub side, and it will add an appropriate configuration block to your local
126 ``git-mirror.conf``. You will still have to manually add the local git hook to
132 You can find the sources in the `git repository`_ (also available `on GitHub`_).
133 They are provided under a `2-clause BSD license`_. See the file ``LICENSE-BSD``
136 .. _git repository: http://www.ralfj.de/git/git-mirror.git
137 .. _on GitHub: https://github.com/RalfJung/git-mirror
138 .. _2-clause BSD license: http://opensource.org/licenses/bsd-license.php
143 If you found a bug, or want to leave a comment, please
144 `send me a mail <mailto:post-AT-ralfj-DOT-de>`_. I'm also happy about pull