Git 進階 - 獲取 fetch


在之前的內容中,有學習總結基本操作、修改撤回、分支 branch、貯藏 stash 、標簽 tag 以及部分遠程操作。

涉及了 Git 的幾個工作區,工作目錄、暫存區、本地倉庫 以及 遠程倉庫
他們之間的用 Git 操作的關系可總結如下圖:


 
 

從本期開始進入Git 的進一步學習

本想先介紹下遠程倉庫的,有幾個好友說很期待看 fetch,所以進階首篇,學習 fetch 命令,也會區分下 git fetchgit pull 的使用。

 
 

fetch 概念

git fetchgit pull 是兩個比較相近的命令

git pull 我們已經知道,是從遠程倉庫拉取最新的內容到本地,在 pull 的過程中如果沒有沖突,Git 會自動將最新的內容合並到本地倉庫中,如果有沖突也是需要解決沖突。

fetch 可譯為獲取,官方給出如下說明

git fetch:Download objects and refs from another repository
git pull :Fetch from and integrate with another repository or a local branch

fetch 直譯過來就是從另一個存儲庫下載對象和引用(refs),而 pull 可以看到除了 fetch 之外 還有 integrate(集成),所以大家習慣理解成 pull = fetch + merge,用於本地存儲庫與遠程存儲庫同步。

fetch & pull

我們來具體消化下上面的解釋

在我們進行 commit 的時候,Git 會自動生成一個 commitid(即 SHA1 校驗和),此時如果進行 push 操作,遠程倉庫的對應分支會同步這個 commitid 的內容,同時本地也會保存一份遠程副本。

在入門(一)的時候,我們有提到過,由 Git 管理的目錄會自動生成一個.git 文件夾,.git 文件夾包含着 Git 操作所需要的內容。

在這個文件夾中就保存了 Git 本地倉庫 以及 跟蹤的遠程倉庫的 commitid。


 
 

在上圖目錄 .git/refs 里面有幾個文件夾,比如

  • heads 存放着本地分支
  • remotes 正在跟蹤的遠程倉庫
  • tags 標簽

通過 git branch -a 查看分支,和 .git 文件夾本地以及遠程分支是一致的。

這些文件里面存放的就是對應分支指向的 commitid (如下圖)
HEAD 文件里面存放的是當前的指向(這里也和前面 git branch -a 查看的內容是一樣的)

 
 

 

下面進入正題

  • 假設當前操作的分支為 master 分支

使用 Git 進行提交的時候,會使用 addcommit 命令將修改的文件提交 Git 版本庫,同時在 heads/master(即,本地的當前分支)生成對應的 commitid(圖示中用 cid 表示)。然后,通過 push 同步到遠程倉庫對應的分支中,同時本地也會保存一份遠程的副本,即 origin/master

 
push

 

如果遠程倉庫被其他協同者更新了,若要更新本地內容,使用 push,此時會從遠程獲取的最新內容並合並到本地

 
pull

 

git pull 不同的是 fetch 是從遠程倉庫 origin 的 master 分支獲取最新的內容到 origin/master 分支上,可以比較本地 master 和 origin/master 的差別之后,操作者視情況決定是否進行合並

 
fetch

 

fetch 語法

git fetch 命令語法,詳見官方文檔 https://git-scm.com/docs/git-fetch

git fetch [<options>] [<repository> [<refspec>…​]] git fetch [<options>] <group> git fetch --multiple [<options>] [(<repository> | <group>)…​] git fetch --all [<options>] 

常用語法

git fetch
該命令將某個遠程服務器的更新,全部取回本地。默認情況下,git fetch 取回所有分支的更新。

如果只想獲取特定分支的更新,可以指定分支名
git fetch <repository> <branch>

git fetch origin master

 
 

 

這里有個陌生的標識 FETCH_HEAD

FETCH_HEAD 是什么?

FETCH_HEAD 指的是某個 branch 在遠程服務器上的最新狀態

每一個執行過 fetch 操作的項目都會在 .git/FETCH_HEAD 文件中保存一個 FETCH_HEAD 列表,其中每一行對應着遠程服務器的一個分支,而文件第一行就是當前分支指向的 FETCH_HEAD

 
 

 

執行 git fetch origin master 之后, FETCH_HEAD 就指向了 master 分支,

  • 如果沒有指定遠程分支,那么當前操作的分支對應的遠程分支作為默認的FETCH_HEAD (假設當前在develop 分支 執行命令 git fetch,那么 FETCH_HEAD 指向的就是遠程端 develop 分支的最新提交)
  • 如果遠程沒有對應分支,也就沒有 FETCH_HEAD
  • 如果指定了分支,就將這個分支作為 FETCH_HEAD

這里先插入介紹下可能用到的命令

便於實戰,提前做些數據

  • 將之前創建的 feat_6 分支 push 到了遠程服務器
  • 同時通過 GitHub 創建了一次描述為 “learn fetch” 的提交(添加了一行 add line : learn fetch),模擬多人協同時,遠程倉庫有更新

執行一次 git fetch origin feat_6 FETCH_HEAD 和 origin/feat_6 都更新了

 
 

 

  • fetch 之后,如果想查看 fetch 日志,可以使用 git log FETCH_HEAD
    這里便於查看 log 的區別,將本地分支切換為 feat_6
    最新的一次提交就是從遠端獲取的,但是是本地沒有的日志
     
     
     
     
  • 也可以使用 diff 查看具體的改動
    • git diff FETCH_HEAD [HEAD] 查看的是 HEAD(當前分支)相對於FETCH_HEAD 的區別
    • 如果使用 git diff HEAD FETCH_HEAD 查看的就是,FETCH_HEAD 相對於 HEAD 的改變,注意和上邊做區分
       
       

講到這里,對於 pull = fetch + merge 的說法便是指在同一分支

git pull 
等同於
git fetch
git merge FETCH_HEAD

除了上面的內容,在 fetch 獲取遠程更新之后,可以在它的基礎上創建一個新的分支,比如:
git checkout -b newBranch origin/master
當然也可以 merge 或 rebase 在本地分支上合並遠程分支
git merge origin/mastergit rebase origin/master
(rebase 我們后面也會介紹到)

后記

fetch 這個功能在我平時的工作中也是疏於使用,但是不論使用 GitHub 還是 SourceTree 都可以看到 Fetch,Fetch 之后會提示是否可 pull


 
 
 
 
 
 
2人點贊
 
 


from:https://www.jianshu.com/p/b0a00b4bed89


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM