2015年3月20日 星期五

Git之...雙bare同步

有時候因為操作習慣或備份,會架設兩個git bare,並且希望彼此同步。

雖然git本身並不是用一個git sync做到和所有的repo同步。
但是git有一個叫hook的客製化事件觸發(Pro Git中文版翻譯成掛鉤)

可以在指定的時機,執行指定的動作。
這麼一來可以擴充git很多功能,我想也是因為這樣,git才能和很多open source的工具整合得很好的原因。

現在就來看看,如何做到同步bare

建立Bare

首先,我們要兩個bare

Main  用git init --bare 建立
Mirror  用git clone --mirror --bare <Main Path>建立

讓Mirror成為Main的鏡像,這麼做的原因有兩個,也是我們要放hook的內容
在Mirror執行git push,即可讓Main有Mirror。
在Mirror執行git fetch,即可讓Mirror有Main。
(不過,彼此會互蓋,要小心)

安裝Hook

Git的Server hook有兩個事件可以使用,pre-receive和post-receive
在此,必須安裝在Mirror,client執行 git push時,會先執行
  1. pre-receive
  2. 將你push的內容放到bare裡
  3. 執行post-receive

如果在1.的時候,先git fetch,和Main同步,在3. 的時候git push讓Main和Mirror一樣。
那麼兩邊就可以同步了!

建立clone

Client建議clone Mirror這一邊,操作比較順暢。
如果萬一有人cline了Main,然後提交了,是不是會造成衝突呢?
這是一定的!就像是兩個人對同一個bare做push一樣。

同步衝突

這時,同步機制會卡在pre-receive做完fetch時,無法將你要push上來的東西放好,造成衝突,所以push失敗,這時你要執行git pull將同步好的下載下來,解決衝突,再重新push,即可解決。

Hook內容

最後的問題是hook的shell腳本怎麼寫?
sample的內容好複雜呀!?
我就在此獻醜一下,看看是不是有更好的做法(一定的有的啦)

post-receive

#!/bin/sh
git push

exit 0

pre-receive

#!/bin/sh
git fetch

參考資料 

[1] 7.3 Git 客製化 - Git Hooks

沒有留言:

張貼留言