前言
在我們使用git的時(shí)候用的更新代碼是git fetch作彤,git pull這兩條指令紊遵。
但是有沒(méi)有小伙伴去思考過(guò)這兩者的區(qū)別呢刻伊?
有經(jīng)驗(yàn)的人總是說(shuō)最好用git fetch+git merge怀愧,不建議用git pull册舞。
也有人說(shuō)git pull=git fetch+git merge恭应,真的是這樣嗎并徘?為什么呢暗赶?
既然如此為什么git還要提供這兩種方式呢够委?
1. 相同點(diǎn)
- 首先在作用上他們的功能是大致相同的荐类,都是起到了更新代碼的作用。
2. 不同點(diǎn)
先補(bǔ)充一些git里面相關(guān)的一些知識(shí):
- 首先我們要說(shuō)簡(jiǎn)單說(shuō)git的運(yùn)行機(jī)制茁帽。git分為本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)玉罐,我們一般情況都是寫(xiě)完代碼,commit到本地倉(cāng)庫(kù)(生成本地倉(cāng)的commit ID潘拨,代表當(dāng)前提交代碼的版本號(hào))吊输,然后push到遠(yuǎn)程倉(cāng)庫(kù)(記錄這個(gè)版本號(hào)),這個(gè)流程大家都熟悉铁追。
- 我們本地的git文件夾里面對(duì)應(yīng)也存儲(chǔ)了git本地倉(cāng)庫(kù)master分支的commit ID 和 跟蹤的遠(yuǎn)程分支orign/master的commit ID(可以有多個(gè)遠(yuǎn)程倉(cāng)庫(kù))季蚂。那什么是跟蹤的遠(yuǎn)程分支呢,打開(kāi)git文件夾可以看到如下文件:
- .git/refs/head/[本地分支]
- .git/refs/remotes/[正在跟蹤的分支]
- 其中head就是本地分支琅束,remotes是跟蹤的遠(yuǎn)程分支扭屁,這個(gè)類(lèi)型的分支在某種類(lèi)型上是十分相似的,他們都是表示提交的SHA1校驗(yàn)和(就是commitID)涩禀。
- 但是料滥,不管他們是如何的相似,他們還是有一個(gè)重大的區(qū)別:
-
更改遠(yuǎn)端跟蹤分支只能用git fetch艾船,或者是git push后作為副產(chǎn)品(side-effect)來(lái)改變葵腹。我們無(wú)法直接對(duì)遠(yuǎn)程跟蹤分支操作,我們必須先切回本地分支然后創(chuàng)建一個(gè)新的commit提交屿岂。
在這里插入圖片描述
-
首先假設(shè)我們本地倉(cāng)庫(kù)的 master 分支上 commit ID =1 践宴,orign/mastter中的commit ID =1 ;這時(shí)候遠(yuǎn)程倉(cāng)庫(kù)有人更新了github ogirn庫(kù)中master分支上的代碼,新的代碼版本號(hào)commit ID =2 ,那么在github上 orign/master的commitID=2爷怀,然后我們要更新代碼阻肩。
在這里插入圖片描述
1. git fetch
使用git fetch更新代碼,本地的庫(kù)中master的commitID不變霉撵,還是等于1磺浙。但是與git上面關(guān)聯(lián)的那個(gè)orign/master的commit ID變成了2。這時(shí)候我們本地相當(dāng)于存儲(chǔ)了兩個(gè)代碼的版本號(hào)徒坡,我們還要通過(guò)merge去合并這兩個(gè)不同的代碼版本撕氧,如果這兩個(gè)版本都修改了同一處的代碼,這時(shí)候merge就會(huì)出現(xiàn)沖突喇完,然后我們解決沖突之后就生成了一個(gè)新的代碼版本伦泥。
-
這時(shí)候本地的代碼版本可能就變成了commit ID=3,即生成了一個(gè)新的代碼版本锦溪。
在這里插入圖片描述 相當(dāng)于fetch的時(shí)候本地的master沒(méi)有變化不脯,但是與遠(yuǎn)程倉(cāng)關(guān)聯(lián)的那個(gè)版本號(hào)被更新了,我們接下來(lái)就是在本地合并這兩個(gè)版本號(hào)的代碼刻诊。
2. git pull
-
是用git pull更新代碼的話(huà)就比較簡(jiǎn)單暴力了防楷,看下圖。
在這里插入圖片描述使用git pull的會(huì)將本地的代碼更新至遠(yuǎn)程倉(cāng)庫(kù)里面最新的代碼版本
3. 總結(jié)
- 由此可見(jiàn)则涯,git pull看起來(lái)像git fetch+git merge复局,但是根據(jù)commit ID來(lái)看的話(huà),他們實(shí)際的實(shí)現(xiàn)原理是不一樣的粟判。
- 這里借用之前文獻(xiàn)看到的一句話(huà):
不要用git pull亿昏,用git fetch和git merge代替它。
git pull的問(wèn)題是它把過(guò)程的細(xì)節(jié)都隱藏了起來(lái)档礁,以至于你不用去了解git中各種類(lèi)型分支的區(qū)別和使用方法角钩。當(dāng)然,多數(shù)時(shí)候這是沒(méi)問(wèn)題的呻澜,但一旦代碼有問(wèn)題递礼,你很難找到出錯(cuò)的地方∫准#看起來(lái)git pull的用法會(huì)使你吃驚宰衙,簡(jiǎn)單看一下git的使用文檔應(yīng)該就能說(shuō)服你。
**將下載(fetch)和合并(merge)放到一個(gè)命令里的另外一個(gè)弊端是睹欲,你的本地工作目錄在未經(jīng)確認(rèn)的情況下就會(huì)被遠(yuǎn)程分支更新供炼。當(dāng)然,除非你關(guān)閉所有的安全選項(xiàng)窘疮,否則git pull在你本地工作目錄還不至于造成不可挽回的損失袋哼,但很多時(shí)候我們寧愿做的慢一些,也不愿意返工重來(lái) **