views:

73

answers:

3

Hi, I have local machine (A), testing server (B) and repository server (C).
I have following workflow:

  1. Code something on A
  2. Mirror changes to test machine B
  3. If it works well commit from B to C

For now, I use rsync for mirroring, but since repository grows it takes some time (~10 sec) to get file list from B. I want to use Git instead of rsync, because it would be much faster and I would have local history along with repository C.

The problem is I haven't found any way to do live-mirroring with git. I can do

git add . && git commit -m "mirroring" && git push

on local machine, but what about server?

Is cronjob for every few second

git checkout | awk '{print $2;}' | git checkout

a right way?

P. S.: I new in git and maybe there is more appropriate tools for this job.

A: 

Use the right tool for the right job. I would use unison or something like that to do the mirroring.

I would also commit from A, instead of B. So you can skip mirroring the .git directory on your testing environment, this would make it faster. You can then leave more meaningful commit messages as to what was changed and why... instead of seeing a endless list of "mirroring" message.

fseto
unison is great, thanks!
Andrew
A: 

I don't think a mirroring tool should be necessary, git seems perfect for that. As fseto said, I also recommend commiting on A. Copying your changes to C should be done using git push. Then, what you need to understand is that since B has a working tree, pushing to it is definitely not the way to go. You can (at least, should) only push to bare repositories (a repository without a working tree: what you should have on your server C).

Instead, on B, you can fetch the changes from A (B is a git clone of A). This can be set up on a cronjob, of course. This will be almost a git pull, except that you want to always reflect the HEAD from server A, even if you switch between branches on A, remove commits, branches, etc. So, on B, I would go for the following command:

git fetch origin ; git checkout origin/HEAD

This command will warn you because it will create a 'detached HEAD' state, but that's fine since you don't want to commit on B.

Now finally, the server part:

  1. On C: Create your server repo by git init --bare
  2. On B (or A ?): add your server as a remote: git remote add server <repo-C>
  3. On B (or A ?): If all works well, push your changes to the server, for example: git push server HEAD:master. I'm writing HEAD for being general, but you may want to use a branch instead.

Hoping that my explanations are understandable... :)

François
+1  A: 

Live-mirroring with Git can be done via git hooks.

You can set up update hook, which can execute actions rigt after a branch was updated. Set this hook up at server B. The hook will be launched at B's site each time you push changes to it. Inside this hook, you may just push changes forward to C (for which you should create a remote). The hook would look like this:

#!/bin/bash
git push remote-of-c $3:$1
[ $? -ne 0 ] && { 
  echo 'Mirroring failed, check server settings and try again.'
  exit 1
}

So each time you update B, C will also get updated. If something failed during that push, you'll see the relevant messages in console, and your initial push won't succeed. That's what's called "mirroring", isn't it?

Pavel Shved