1

Is there an automatic way to synchronise a local git repository with a remote one, for backup?

Basically the structure that I'm envisaging is this:

  • "Master" repository on a central server
    • User A's PC has a local clone of the master repo
      • Backup server has a mirror of user A's repo
    • User B's PC has a local clone of the master repo
      • Backup server has a mirror of user B's repo

Interaction between the users and the master is manual -- the users have to choose when to push or pull changes.

Interaction between the users and their personal backup is automatic -- whenever the user commits any change (on any branch, including creating new branches) to their local repo it should immediately be pushed to the backup repo if the server is reachable, and otherwise held without error until the server is reachable (or the next action when the server is reachable, if that's easier) and then pushed. (ie. it should tolerate periods of disconnection but after reconnecting then the repos should be a complete mirror again, including changes made while disconnected).

A user should never need to consciously push to the backup server. They might want to clone a new repo off the backup server (eg. if their hard drive dies or they need to use a second PC for a while). User B might want to pull a branch from user A's backup repo (though this will be rare; usually branches will be exchanged via the master repo). But mostly it should just be invisible to them.

And it should be as immediate as possible, not a scheduled task, because they might commit and then shut down or disconnect from the network, and I would still like the backup to be up to date in this case.

Setting up the master and personal clones is easy. But how do I set up this backup mirroring?

Also, while mirroring just the committed changes is ok, it might be nice if it could somehow also mirror uncommitted changes (including unversioned but not ignored files). I'm ok with not doing that though (as I suspect it'd get messy).

Miral
  • 12,637
  • 4
  • 53
  • 93
  • Does this mirror-thing have to be done with `git`? As long as I understand, all you want is a folder backup as git is self-concluded. `rsync` might help? – J Jiang Mar 11 '14 at 02:21
  • It does not have to be done with git itself (although I would assume that this would be more efficient), but it does need to tie into git in some way (eg. a hook) to synchronise at the appropriate times. Also I'm primarily targeting Windows users, although there might be a few Linux boxes sprinkled in too. – Miral Mar 11 '14 at 06:10

1 Answers1

0

That should involve a post-commit hook, which needs to be deployed on each client repo.
Or that hook could be part of a git template repo that all users are using when using git init: see git init "TEMPLATE DIRECTORY" section.

That hook would be in charge of pushing to a backup bare repo, and could be as simple as this one.

#!/bin/sh 
git push --mirror remote-name

You will find similar ideas in "How to automatically push after committing in git?".

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Will that push all branches or just the active one? And what happens if the remote is not accessible at that time? Will it "catch up" later? – Miral Mar 11 '14 at 07:58
  • @Miral a `push --mirror` will actually push everything. And yes, if that fails, the next push will catch up, and push the updated delta. – VonC Mar 11 '14 at 08:01
  • Sounds good; I'll give it a try and get back to you. Regarding the point about `git init` -- do hooks get cloned when using `git clone` as well, or not? If not, I'm not sure how a template is useful since it's likely to be a one-time-per-user-PC thing. – Miral Mar 11 '14 at 08:36
  • @Miral no, hooks don't get clone, unless you have defined a template directory accessible by all users, for them to use automatically when doing a `git init`. Then the hooks defined in that template get copied to the new repo. – VonC Mar 11 '14 at 08:38