Jay Taylor's notes
back to listing indexAutomatic synchronization of 2 git repositories | Pragmatic Source
[web search]Articles
-
24/04/2009
-
09/03/2009
-
20/02/2009
-
18/02/2009
News
-
Wednesday 21 January 2009
-
Wednesday 17 October 2007
-
Thursday 14 June 2007
Contributions
Toutes les contributions de Pragmatic Source, que ce soit sous forme d'articles, de présentations ou de code sous licence libre, sont disponibles dans cette section du site et sur notre Référentiel Open Source (Redmine).
All of our contributions (articles, slideshows, Open Source code) are available in this section and on our Open Source Repository (Redmine).
Automatic synchronization of 2 git repositories
-
You are fond of GitHub, the decentralized source control management site?
-
You are a happy user of Redmine as a project management tool?
But at the same time you are facing a difficult choice: putting your Git code repository on GitHub to benefit from its ergonomic web interface and team cooperation capabilities or putting it on Redmine to interface source control management and ticket tracking?
Then this article is for you! It explains how to automatically synchronize your Git repositories between GitHub and Redmine!
Description
This technical tip is for the Git Distributed Source Control Management tool. It explains how to configure a read-only copy of a remote Git repository on a local
server in bare mode and automatically synchronize its contents (one way only, from the remote repository to the local copy).
Use case
Lets suppose I use GitHub to store some of my projects but at the same time I want to have a local repository copy at hand in order for Redmine to link source code revisions and tickets together in the « Activity » tab, like in this example.
Redmine can only index a local Git repository, as opposed to Subversion whose repository can be accessed remotely, it is therefore necessary to maintain a local repository on the Redmine server.
Configuration
Let's suppose that:
- We host a project on GitHub, for example http://github.com/Farzy/multilog-axfr
- We have a local Redmine instance, for example http://opensource.pragmatic-source.com/projects/show/multilog-axfr
- The local Git repository on the server hosting Redmine is:
/srv/gitosis/repositories
Creating a local bare repository
On the Redmine / Git server:
- We clone the GitHub repository locally in bare mode. In this example the URL of the remote repository is:
git://github.com/Farzy/multilog-axfr.git
.
cd /srv/gitosis/repositories git clone --bare git://github.com/Farzy/multilog-axfr.git multilog-axfr.git
Output:
Initialized empty Git repository in /srv/gitosis/repositories/multilog-axfr.git/
remote: Counting objects: 76, done.
remote: Compressing objects: 100% (67/67), done.
remote: Total 76 (delta 31), reused 0 (delta 0)
Receiving objects: 100% (76/76), 25.33 KiB, done.
Resolving deltas: 100% (31/31), done.
- We must now manually configure the remote branch tracking and then synchronize the repositories:
cd multilog-axfr.git git remote add origin git://github.com/Farzy/multilog-axfr.git git fetch -v
Output:
From git://github.com/Farzy/multilog-axfr
* [new branch] master -> origin/master
Automatic repository synchronization
Usually, a working copy is updated with the following commands:
git fetch origin git merge origin
But merging does not work with a bare repository. We have to cheat. We're going to use the following commands, that we will launch automatically using the cron task scheduler.
Let's suppose that:
- The local git repositories belong to the
gitosis
user, - The server's
cron
version supports advanced functionalities like the/etc/cron.d/
folder.
We can then use the following configuration file, /etc/cron.d/synchronize-git-respositories:
# One-way synchronization of a local and remote bare Git repository. # Repeat this line for each repository. */30 * * * * gitosis cd /srv/gitosis/repositories/multilog-axfr.git && git fetch origin && git reset refs/remotes/origin/master > /dev/null
The local repository will automatically be updated every half hour.
Explanations
git fetch
updates the refs/remotes/origin/master reference without touching the HEAD branch.
git reset refs/remotes/origin/master
make the HEAD branch point to the same commit as the remote branch.
It's done!
A word of caution
-
You must not commit in the local repository or you'll loose all your changes after the automatic synchronization: the local repository is read-only, for Redmine's use only for example.
-
The cron script does not check all potential errors. The «
> /dev/null
» redirection is necessary because the «git reset
» command, when executed on a bare repository, displays some messages (see below) that we always want to ignore:
multilog-axfr.git % git reset refs/remotes/origin/master .gitignore: needs update LICENSE: needs update README.md: needs update Rakefile: needs update bin/multilog-axfr.rb: needs update multilog-axfr.conf-sample: needs update samples/root/slaves/farzy.org: needs update samples/root/slaves/linux.org: needs update samples/root/slaves/pragmatic-source.com: needs update test/slave_zones_spec.rb: needs update
Thanks to this system your code base can peacefully coexist on both Redmine and GitHub!
Comments
git reset refs/remotes/origin do not work,
I get error on running git reset refs/remotes/origin
git reset refs/remotes/origin
fatal: This operation must be run in a work tree
fatal: Could not reset index file to revision 'refs/remotes/origin/master'.
#
Do we need to run that command or git fetch origin will be fine ?
second git command fails to
second git command fails to me with:
[root@loc initr.git (BARE:initr)]$ git reset refs/remotes/origin/master
fatal: This operation must be run in a work tree
fatal: Could not reset index file to revision 'refs/remotes/origin/master'.
git version 1.6.2.4
Re: second git command fails to
Hi,
That's strange, maybe something changed in recent git versions?
I am running git version 1.5.6.5 on my server. I'll make some tests and updated the article if I can.
Thanks for the information.
I'm getting the same issue.
I'm getting the same issue. Any resolution yet?
I'm running Git version 1.6.0.4
git reset fix
It looks like it works if you include the "--soft" option.
git reset --soft refs/remotes/origin/master
good stuff. in "Redmine can
good stuff.
in "Redmine can only index a local Git repository, in opposition to Subversion", it should probably say "as opposed to", rather than "in opposition".
cheers.
With a recent version of git...
The process is simpler when using a recent git version (>=1.6.0). There is no more need to reset if you clone the repository with the mirror option.
git clone --mirror user@server:project.git
Then, you just need to fetch on a regular basis.
cd path/to/local/project.git && git fetch -q
What links here
No backlinks found.