GitHub可以通過多種途徑為版本庫授權(quán),讓版本庫成為多人共享的版本庫毅往,從而讓項(xiàng)目管理者圍繞項(xiàng)目創(chuàng)建一個核心開發(fā)團(tuán)隊(duì)。
傳統(tǒng)的集中式版本控制系統(tǒng),如CVS全释、SVN正勒,所有用戶都訪問同一個版本庫拣展。采用集中式工作模式的GitHub用戶也同樣是訪問同一版本庫拜银。
對于由用戶gotgithub創(chuàng)建的helloworld版本庫,添加了合作者supergirl和incredible阴汇,三個人克隆版本庫使用如下命令数冬。
- 用戶 gotgithub 克隆版本庫。
gotgithub$ git clone https://gotgithub@github.com/gotgithub/helloworld.git
- 用戶 supergirl 克隆版本庫搀庶。
supergirl$ git clone https://supergirl@github.com/gotgithub/helloworld.git
- 用戶 incredible 克隆版本庫拐纱。
incredible$ git clone https://incredible@github.com/gotgithub/helloworld.git
對于像Git這樣的分布式版本控制系統(tǒng)铜异,提交總是會成功,這是因?yàn)樘峤徊⒉簧婕昂凸蚕矸?wù)器的交互秸架,是針對本地克隆版本庫進(jìn)行的本地操作揍庄。采用集中式的工作模式,共享版本庫作為各個用戶各自本地版本庫數(shù)據(jù)交換咕宿、溝通的中介,只有在本地克隆版本庫需要和共享版本庫同步的時候才要和服務(wù)器建立連接蜡秽。實(shí)際上無論采用分布式還是集中式的工作模式府阀,Git都好像工作在一個獨(dú)立的分支上(克隆即分支),即使共享版本庫和本地克隆版本庫的分支名都叫做master芽突。
三個用戶克隆gitgithub/helloworld版本庫后试浙,各自在本地執(zhí)行了一次或多次提交。三個用戶各自的提交都會非常順利寞蚌,但是一旦決定將本地提交推送到共享服務(wù)器時就可能遇到麻煩田巴。用戶 gotgithub 先執(zhí)行推送,會非常順利挟秤。而其他人就沒有這么幸運(yùn)了壹哺,會報告錯誤:遇到非快進(jìn)式推送(non-fast-forward)。Git的推送操作就像SVN等集中式版本控制系統(tǒng)的提交操作那樣艘刚,先執(zhí)行者成功管宵,后執(zhí)行者糟糕(要解決沖突,自動或手動)攀甚。
合并后推送
GitHub并不對強(qiáng)制推送進(jìn)行限制箩朴,但是用戶不要用git push -f命令強(qiáng)制推送,因?yàn)槟菢訒采w掉共享版本庫中用戶gotgithub的推送秋度,正確的做法是獲取共享版本庫中新提交炸庞,并在本地版本庫中和本地提交合并。即執(zhí)行:
supergirl$ git fetch
supergirl$ git merge
實(shí)際上用戶supergirl只需執(zhí)行一條命令便可完成所有的操作:
supergirl$ git pull
即:git pull = git fetch + git merge荚斯。
但是合并操作并不總是會成功埠居,如果自動合并失敗,會在暫存區(qū)對合并前后文件進(jìn)行標(biāo)識事期,工作區(qū)進(jìn)入沖突解決狀態(tài)拐格,在沖突解決完成之前不能提交。Git支持多種圖形工具幫助完成沖突解決刑赶,執(zhí)行如下命令捏浊,即可自動調(diào)用已安裝的沖突解決工具。
supergirl$ git mergetool
沖突解決完畢撞叨,執(zhí)行提交即完成沖突解決金踪。如果在沖突解決過程把本地文件搞得一團(tuán)糟浊洞,隨時可以取消合并操作。執(zhí)行命令git reset --hard會取消沖突的合并讓本地版本庫回到合并之前的狀態(tài)胡岔。
成功完成合并后將本地版本庫中的提交推送到共享版本庫:
supergirl$ git push
合并還是變基
合并并非多個開發(fā)者的工作成果融合的唯一選擇法希,有時甚至并非最佳選擇。一方面合并會產(chǎn)生除了合并雙方(或多方)所有提交外的一個新提交靶瘸,增加了代碼審核的負(fù)擔(dān)苫亦,另一方面本地多個提交混雜一起與遠(yuǎn)程分支合并會更困難。在特定情況下怨咪,變基是合并之外的另一個選擇屋剑。
圖中右上是合并操作后的結(jié)果,右下是變基操作后的結(jié)果诗眨。
若用戶 incredible 選擇變基操作唉匾,執(zhí)行命令如下:
- 獲取遠(yuǎn)程版本庫的提交到本地的遠(yuǎn)程分支。
incredible$ git fetch origin
- 執(zhí)行變基操作匠楚,將本地master分支的提交變基到新的遠(yuǎn)程分支中巍膘。
incredible$ git rebase origin/master
如果一切順利,變基后推送到共享版本庫芋簿。
incredible$ git push