跳至主要内容

【Git】Git fetch 是做什麼的?

在剛開始學 git 的時候,只知道 git fetch 是把檔案抓下來,git merge 是合併到本地端,當學到 git pull 時,得知

git pull = git fetch + git merge

至此之後,就只用過 git pull 而再也沒用過 git fetch 了。

最近突然覺得,咦?啊 git fetch 到底有什麼用,好奇心驅下才讓我好好的去瞭解 git fetch 的作用,也才有了這一篇學習記錄。

Git fetch 沒有真的抓 code 下來​

之前我一直以為 git fetch 是把 code 抓下來,放在某個檔案,等到 git merge 才會合併到主要檔案。

實際去瞭解才知道當一開始 git clone 把專案下載到本地端時,就會建立所有分支的 Remote tracking branch,而這個所謂的遠端追蹤分支其實只是把所有分支最新的 commit ID 給紀錄下來。

而我秉持著實事求是的精神,在專案底下的隱藏資料夾 .git 裡面的 packed-refs 找到了所有的遠端分支。



可以看到所有的分支都是以 commit ID 來做儲存的,而 git fetch 就是去檢查遠端分支的 commit 有沒有變動,當發現有所不同,就會更新 commit ID。

當執行 git merge 時,才會根據記錄的 commit ID 去抓取雲端的 code,並合併在本地端裡。

fetch 後 compare​

當 fetch 新的 commit ID 下來後,如果要比較跟本地端的不同,可以使用 git diff <tracking branch> 來做比較,遠端的分支名稱通常都會是 origin/<branch name>





不過看起來有點醜,如果改的地方太多就很不方便查看,所以我都會使用 Git Graph 來看,只要點一下 commit 就可以看到更改了什麼檔案,還可以點擊更改的檔案來打開編輯器去比對內容,是不是很方便啊~



小技巧

如果想比對兩個離很遠的 commit,只要在 git graph 點擊一個 commit,按住 command 再點擊另一個 commit,就可以顯示兩個分支的不同了喔!

刪除 tracking branch​

假設你的遠端分支已經被刪除,但是本地端的 tracking branch 還在,這時候可以使用 git fetch --prune 來同步遠端分支跟本地端的 tracking branch,如果遠端已經不存在,就會刪除本地端的 tracking branch。

git fetch --prune # or git fetch -p

設定自動 fetch​

在 Vscode 裡面可以設定自動 fetch 跟間隔秒數,預設是 false。



而如果想要在 fetch 的時候,自動刪除遠端分支已經不存在的 tracking branch,可以在 vscode 尋找 fetch and prune,可以設定 git 或是 git graph 預設的 fetch 行為。



只 fetch 有什麼優點​

講了那麽多,那到底下 git fetch 有什麼優點呢?

先 fetch 的好處:

  • 可以先檢查有什麼不同,再來進行 merge,提前知道改了什麼,遇到 conflict 時才不會緊張。
  • 可以 fetch 過後再來決定要用 merge 還是要用 rebase。

好像其實也沒什麼特別的優點XD就只是可以提早檢查有沒有什麼不同。

我有同事會先 fetch 之後看有什麼不同,再進行 merge,不過如果你有設定 vscode 的 auto fetch 的話,基本上 git merge 就可以了!最主要還是看個人喜好拉~

補充

git fetch 會把遠端的所有分支最新的 commit ID 給紀錄下來,而 git pull 中的 git fetch 只會抓取當前分支的 commit ID。就這點來看,純下 git fetch 還是有它的用處的!