Two way git mirror: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
imported>Hendrik Brummermann Created page with "== Motivation == == Setup == == Mirror == We use the following script to do the actually mirroring. It can be invoked with the name of a known repository as parameter or wi..." |
imported>Hendrik Brummermann added support for tags |
||
| (28 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
This articles describes how to setup a two way mirror of git repositories. I hope this article will be helpful as it works around a number of caveats for two way git mirrors. |
|||
== Motivation == |
|||
== Setup == |
== Setup == |
||
We create a clone from either of the upstream repositories. It is important that the repository is bare. |
|||
| ⚫ | |||
<source lang="bash"> |
|||
cd /srv/gitsync |
|||
git clone --bare git@github.com:[account]/[repository].git |
|||
mv [repository].git [repository] |
|||
</source> |
|||
Now we delete remote "origin" and configure a remote setting for each upstream repository instead: |
|||
<source lang="bash"> |
|||
cd [repository] |
|||
git remote remove origin |
|||
git remote add github git@github.com:[account]/[repository].git |
|||
git remote add sourceforge ssh://[account]@git.code.sf.net/p/[repository]/code |
|||
</source> |
|||
The mirroring should happen right after changes have been pushed to one of the repositories. Therefore a webhook is required to trigger the mirror script. |
|||
On Sourceforge a project admin needs to enable it at Admin -> Tools -> Repository -> Webhooks. On Github it is at Settings -> Webhooks & Services -> Add Webhook. |
|||
| ⚫ | |||
We use the following script to do the actually mirroring. It can be invoked with the name of a known repository as parameter or with the "--all" flag. |
We use the following script to do the actually mirroring. It can be invoked with the name of a known repository as parameter or with the "--all" flag. |
||
| Line 17: | Line 37: | ||
git fetch --all -p |
git fetch --all -p |
||
# push branches from sourceforge to github and via versa. |
# push branches from sourceforge to github and via versa. |
||
git push github "refs/remotes/sourceforge/*:refs/heads/*" |
git push github "refs/remotes/sourceforge/*:refs/heads/*" "refs/tags/*:refs/tags/*" |
||
git push sourceforge "refs/remotes/github/*:refs/heads/*" |
git push sourceforge "refs/remotes/github/*:refs/heads/*" "refs/tags/*:refs/tags/*" |
||
} |
} |
||
| Line 56: | Line 76: | ||
// validate repository name to prevent injection and traversing attacks |
// validate repository name to prevent injection and traversing attacks |
||
$repo = $_REQUEST['repository']; |
$repo = $_REQUEST['repository']; |
||
if (!preg_match('/^[a-zA-Z0-9]$/', $repo)) { |
if (!preg_match('/^[a-zA-Z0-9]+$/', $repo)) { |
||
die('invalid repository name'); |
die('invalid repository name'); |
||
} |
} |
||
| Line 63: | Line 83: | ||
system('sudo -Hu gitsync /usr/local/bin/gitsync '.$repo); |
system('sudo -Hu gitsync /usr/local/bin/gitsync '.$repo); |
||
</source> |
</source> |
||
== Security == |
== Security == |
||
| Line 72: | Line 91: | ||
== Deleting branches == |
== Deleting branches == |
||
There is one caveat: Deletion of branches is not mirrored, but deleted branches are resurrected by the mirror script. |
|||
To delete a branch for good, the following commands need to be executed in quick succession. |
|||
<source lang="bash"> |
|||
git branch -d [branchName] |
|||
git push github --delete [branchName] |
|||
git push sourceforge --delete [branchName] |
|||
</source> |
|||