2ec3bc057ecee59622348e397b0604ea2f5ac9bc
[git-mirror.git] / README.rst
1 git-mirror - Sync your git repositories
2 =======================================
3
4 Introduction
5 ------------
6
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_.
13
14 .. _git-mirror: https://www.ralfj.de/projects/git-mirror
15 .. _gitolite: http://gitolite.com/gitolite/index.html
16 .. _GitHub: https://github.com/
17
18 Setup (gitolite)
19 ----------------
20
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``.
26
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::
29
30   mail-sender = git@example.com
31
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``::
35
36   LOCAL_CODE                =>  "$rc{GL_ADMIN_BASE}/local",
37
38 Make sure you read the `security note 
39 <http://gitolite.com/gitolite/non-core.html#pushcode>`_ concerning this 
40 configuration.
41
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 
44 content::
45
46   #!/bin/sh
47   exec ~/git-mirror/githook.py
48
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``::
51
52   option hook.post-receive = git-mirror
53
54 (If you need multiple hooks here, you can separate them by spaces.)
55
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``::
58
59   [repo-name]                                                                                                                                                                                                                                     
60   owner = email@example.com                                                                                                                                                                                                                  
61   local = /home/git/repositories/repo-name.git                                                                                                                                                                                                    
62   deploy-key = ssh-key                                                                                                                                                                                                               
63   mirror-a = git@server2.example.com:repo-name.git
64   mirror-b = git@server2.example.org:the-repo.git
65
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 errors occurring 
69 during synchronization are sent to. And finally, the URLs to push to are given 
70 by ``mirror-<something>``. If these other servers also run gitolite and have a 
71 symmetric setup, then no matter where a change is pushed, git-mirror will 
72 forward it to all the other repositories.
73
74 Setup (GitHub)
75 --------------
76
77 If one of the to-be-synced repositories is on GitHub, you can obviously not use 
78 the procedure above to sync changes that are arriving at GitHub, to the other 
79 repositories. Instead, we will use a webhook, such that GitHub tells your server 
80 that a change happened, and then your server can pull the changes to its local 
81 repository and synchronize all the others. This assumes that the server running 
82 the webhook also hosts one of the copies of the git repository.
83
84 First of all, you will have to configure your webserver to run ``webhook.py`` as 
85 CGI script. Consult the webserver documentation for more details.
86
87 Secondly, ``webhook.py`` needs to be able to find the main git-mirror scripts, 
88 and it needs to be able to execute them as the ``git`` user. For the first 
89 point, open ``webhook.py`` and change ``webhook_core`` to point to the file 
90 ``webhook-core.py`` in your git-mirror clone. If your installation matches the 
91 paths I used above, that should already be the case. For the second point, 
92 ``webhook.py`` is using ``sudo`` to elevate its privileges. You need to tell 
93 ``sudo`` that this is all right, by creating a file 
94 ``/etc/sudoers.d/git-mirror`` with content::
95
96   www-data        ALL=(git) NOPASSWD: /home/git/git-mirror/webhook-core.py
97
98 Now, if you visit ``https://example.com/git-mirror/webhook.py`` (replace with 
99 your URL), the script should run and tell you ``Repository missing or not 
100 found.``.
101
102 The next step is to add this as a webhook to the GitHub repository you want to 
103 sync with, to create a fresh SSH key and configure it as deployment key for the 
104 repository, and to configure git-mirror accordingly. For additional security, 
105 one should also configure a shared HMAC secret, such that the webhook can verify 
106 that the data indeed comes from GitHub.
107
108 To make your job easier, there is a script ``github-add-hooks.py`` that can do 
109 all this for you. It assumes that the repository exists on the GitHub side, but 
110 has not yet been configured for git-mirror at all.
111
112 To give the script access to your repositories, you need to create an access 
113 token for it. Go to "Personal Access Tokens" in your GitHub configuration, and 
114 create a new token with the permissions ``admin:repo_hook`` and ``public_repo``. 
115 Add the token and the webhook URL to the top part of ``git-mirror.conf`` (right 
116 below ``mail-sender``)::
117
118   github-token = pastethetokenhere
119   webhook-url = https://example.com/git-mirror/webhook.py
120
121 Now you can call the automatic setup script as follows::
122
123   ./github-add-hooks.py -o UserName -e email@example.com \
124     -l ~/repositories/repo-name.git/ -n github-repo-name
125
126 Notice that the username is case-sensitive! This will do all the setup on the 
127 GitHub side, and it will add an appropriate configuration block to your local 
128 ``git-mirror.conf``. You still have to manually add the local git hook to 
129 gitolite. Once you are done, any push happening to either gitolite or GitHub
130 will be visible on the other side immediately. This applies even to pull
131 requests that you merge in the GitHub web interface.
132
133 Source, License
134 ---------------
135
136 You can find the sources in the `git repository`_ (also available `on GitHub`_). 
137 Guess what, the two are synced with this tool ;-) . They are provided under a 
138 `2-clause BSD license`_. See the file ``LICENSE-BSD`` for more details.
139
140 .. _git repository: http://www.ralfj.de/git/git-mirror.git
141 .. _on GitHub: https://github.com/RalfJung/git-mirror
142 .. _2-clause BSD license: http://opensource.org/licenses/bsd-license.php
143
144 Contact
145 -------
146
147 If you found a bug, or want to leave a comment, please
148 `send me a mail <mailto:post-AT-ralfj-DOT-de>`_. I'm also happy about pull
149 requests :)