1.前言
Git的本地使用僅僅服務(wù)于個(gè)人鼠锈,若想多人合作郭膛,還是得通過(guò)網(wǎng)絡(luò)和遠(yuǎn)程倉(cāng)庫(kù)來(lái)共享和同步晨抡。這時(shí)就面臨著如何獲取代碼,如何更新代碼则剃,如何解決沖突和如何上傳代碼等問(wèn)題耘柱。只要了解了這些,便可以在工作中舒服地使用Git了棍现。
2.從遠(yuǎn)端獲取
作為一名開(kāi)發(fā)者调煎,最常遇到的情況便是中途參與一個(gè)項(xiàng)目,那么獲取已經(jīng)完成的代碼轴咱,在此基礎(chǔ)上開(kāi)發(fā)是必修課汛蝙。
2.1.下載到本地
遠(yuǎn)程倉(cāng)庫(kù)是存在服務(wù)器上的,需通過(guò)網(wǎng)絡(luò)地址去訪(fǎng)問(wèn)朴肺。而git clone
便可以通過(guò)網(wǎng)址下載倉(cāng)庫(kù)的代碼窖剑,支持的協(xié)議有:http/https,ssh戈稿,git西土,file,ftp/ftps鞍盗,rsync需了。
由于下載的內(nèi)容在本地會(huì)用文件夾存儲(chǔ)跳昼,目錄名默認(rèn)與遠(yuǎn)程倉(cāng)庫(kù)的一致。若想修改肋乍,可以在git clone
的命令最后添加目錄名作為參數(shù)鹅颊。
當(dāng)代碼下載完畢后,Git會(huì)給網(wǎng)址取個(gè)別名方便用戶(hù)使用墓造,專(zhuān)業(yè)的稱(chēng)呼為主機(jī)名堪伍,默認(rèn)是origin,可通過(guò)git remote
查看觅闽。若想知道遠(yuǎn)程倉(cāng)庫(kù)的網(wǎng)址帝雇,后加-v
即可。若想修改主機(jī)名蛉拙,在git clone
時(shí)尸闸,在網(wǎng)址前添加-o <主機(jī)名>
,或者git remote rename <原主機(jī)名> <新主機(jī)名>
便可改變孕锄。
默認(rèn)分支是master吮廉,但開(kāi)發(fā)通常是基于develop或feature分支,具體在之后的Gitflow工作流中會(huì)詳細(xì)講解硫惕。這時(shí)得切換分支茧痕,那如何知道有哪些分支呢野来?git branch
可以查看分支恼除,后加-r
只顯示遠(yuǎn)程分支,而-a
顯示本地和遠(yuǎn)程的分支曼氛。更強(qiáng)大的是git remote show <主機(jī)名>
豁辉,不僅顯示遠(yuǎn)程分支,還顯示網(wǎng)址舀患、HEAD以及本地分支與遠(yuǎn)程分支的映射關(guān)系徽级。
2.2.更新到本地
Git不會(huì)主動(dòng)從遠(yuǎn)程倉(cāng)庫(kù)上更新代碼,當(dāng)覺(jué)得遠(yuǎn)端有新的內(nèi)容時(shí)聊浅,可通過(guò)git fetch
取回本地餐抢。但是,存放在<主機(jī)名>/<分支名>
下低匙,對(duì)于開(kāi)發(fā)的分支沒(méi)有影響旷痕,所以不改變工作區(qū)文件。
3.同步工作區(qū)
上一篇中提到過(guò)工作區(qū)的文件由本地分支和版本來(lái)決定顽冶。為了改變工作區(qū)從而改變IDE或Explorer中看到的內(nèi)容欺抗,需要將正在使用的本地分支與映射的遠(yuǎn)程分支(已更新)進(jìn)行合并,而且合并的過(guò)程中可能會(huì)出現(xiàn)沖突强重,這些都需要解決绞呈。
3.1.merge
git merge
是比較常用的合并命令贸人,默認(rèn)使用Fast-forward方式,即當(dāng)不存在沖突時(shí)佃声,將兩個(gè)分支的提交(commit)按時(shí)間先后排序并依次合并艺智,同時(shí)刪除合并分支的提交信息。當(dāng)用git log --graph
或gitk
查看記錄時(shí)圾亏,不會(huì)感覺(jué)有合并的操作力惯,除了所有的指針都跑到一起(HEAD、<所在分支指針>召嘶、<合并指針>)父晶,如下圖右半部分(忽略了指針)。在團(tuán)隊(duì)合作時(shí)弄跌,這樣不能直觀地看出人員的操作甲喝,通常用git merge --no-ff
命令代替,禁用Fast-forward方式铛只,保留所有的操作信息埠胖,如下圖左半部分。
3.2.rebase
git rebase
的目的也是為了合并淳玩,不過(guò)原理不同直撤。它是將所在分支的所有提交轉(zhuǎn)為補(bǔ)丁(patch)移到.git/rebase
目錄下暫存蜕着,再將指針指向合并分支的末尾谋竖,并應(yīng)用那些補(bǔ)丁。當(dāng)用git log --graph
或gitk
查看記錄時(shí)承匣,也不會(huì)感覺(jué)有合并的操作蓖乘。
3.3.conflict
若是僅僅看上面的內(nèi)容,似乎差異體現(xiàn)在合并后提交信息的展示順序上韧骗。其實(shí)當(dāng)發(fā)現(xiàn)沖突(conflict)時(shí)驰吓,處理的方式上會(huì)有明顯的不同沈贝。首先解釋一下什么是沖突站削?當(dāng)合并時(shí)發(fā)現(xiàn)不同的分支修改了相同的位置攘蔽,Git不知道誰(shuí)是正確的,所以需用戶(hù)自己選擇政模,解決沖突岗宣。
- merge會(huì)執(zhí)行完合并操作,在工作區(qū)文件中用
<<<<<<<
览徒、=======
和>>>>>>>
標(biāo)記出沖突的地方狈定。開(kāi)發(fā)人員解決后,再執(zhí)行一次提交變化的操作,表示修改錯(cuò)誤即可纽什。這次提交將出現(xiàn)在提交記錄中措嵌,并成為最新的版本。 - rebase則是出現(xiàn)沖突就暫停操作芦缰,等開(kāi)發(fā)人員解決了企巢,通過(guò)命令
git add
添加變化和git rebase --continue
繼續(xù)操作,任何時(shí)候都可以git rebase --abort
來(lái)終止操作让蕾,回到rebase前的狀態(tài)浪规。好處是,記錄不會(huì)多出解決沖突的提交探孝;壞處是笋婿,沖突多時(shí)得重復(fù)處理。 -
git fetch
和git merge
可以用git pull
代替顿颅,而git fetch
和git rebase
可以用git pull --rebase
代替缸濒。
4.推送到遠(yuǎn)端
代碼同步好了,自然就應(yīng)該開(kāi)始工作了粱腻”优洌可是團(tuán)隊(duì)合作時(shí)如何讓其他人接收到你的更新呢?首先绍些,須將遠(yuǎn)程倉(cāng)庫(kù)作為中轉(zhuǎn)站捞慌,更新的代碼都推送上去,別人主動(dòng)從遠(yuǎn)程倉(cāng)庫(kù)下載更新柬批。
4.1.正常推送
假設(shè)不會(huì)在遠(yuǎn)程倉(cāng)庫(kù)那沖突的話(huà)啸澡,只需要按照git push <主機(jī)名> <本地分支名>:<遠(yuǎn)程分支名>
輸入命令即可。由于本地分支默認(rèn)映射的是固定主機(jī)的固定遠(yuǎn)程分支萝快,即origin上的同名分支锻霎,所以簡(jiǎn)寫(xiě)git push
著角。
需注意的是揪漩,若寫(xiě)了本地分支而與之映射的分支在遠(yuǎn)端沒(méi)有,則會(huì)在遠(yuǎn)端新建同名分支吏口;若省略本地分支而寫(xiě)了遠(yuǎn)程分支奄容,則會(huì)刪除此遠(yuǎn)程分支。當(dāng)想改變分支的映射關(guān)系产徊,只需某次推送時(shí)昂勒,在主機(jī)名前加-u
就可以設(shè)置此主機(jī)為默認(rèn)主機(jī)。
4.2.推送前更新
若別人在你之前推送了代碼舟铜,且包含你修改的文件戈盈,那么在推送時(shí)就會(huì)沖突。為了避免這種情況的發(fā)生,規(guī)范的做法是先更新本地需提交的分支塘娶,合并有差異的地方(參照同步工作區(qū))归斤,再進(jìn)行推送。當(dāng)然刁岸,若你覺(jué)得遠(yuǎn)程倉(cāng)庫(kù)上代碼是可以忽略掉的脏里,在主機(jī)名前加--force
即可覆蓋遠(yuǎn)程倉(cāng)庫(kù)上的同名文件。
5.總結(jié)
到此已經(jīng)可以使用Git完成一個(gè)操作流程虹曙,比如向GitHub上提交自己的開(kāi)源項(xiàng)目迫横。但是這些仍然不足以讓你在較大規(guī)模的公司中游刃有余,還需要懂得如何合理地利用分支酝碳、標(biāo)簽實(shí)現(xiàn)功能的并行開(kāi)發(fā)矾踱,如何通過(guò)Gerrit結(jié)合Git實(shí)現(xiàn)CodeReview等。