[Git] Checkout - 從檔案庫取出資料

  • 14406
  • 0
  • Git
  • 2016-05-06

使用 checkout 指令從指定節點取出當時的檔案內容

前言

版本控管就是要讓我們可以輕易地取得歷史軌跡中某個時間點的檔案,因此我們可以簡單透過 checkout 指令來取出特定版本的檔案;另外,亦可透過相同指令讓我們遊走於各個分支(Branch)間,完成分支所賦予需達成的目標。以下介紹可以透過 checkout 來達成的功能有哪些。

 

環境

  • git v2.8.1.windows.1
  • SourceTree  v1.3.8.0

 

功能說明

我們可以透過 checkout 指令完成許多實用的功能,以下將就筆者所接觸到的相關功能進行說明。

 

將檔案內容回復至指定節點

當用戶需將資料從 index 或 repository 取出時,可以利用 checkout 指令來取出特定版本的檔案;這邊需要特別注意的是,取出的資料檔案會直接覆蓋檔案內容,並且會自動將有異動部份加入 index 中,因此目前未提交的變更都會消失(被覆蓋),請謹慎使用。 以下說明兩種檔案回復方式供參考。

git checkout 檔案:檔案將回復至最新版本,從 index 開始追朔

由於未指定特定節點,因此工作目錄中的指定檔案將回復至最新版本,而最新版本範圍會包含目前加入 index 的檔案,因此請特別注意 Git 會從 index (staged file) 開始尋找是否有該檔案存在,若有則回復至先前透過 git add 所加入 index 的版本,若否則會繼續由新至舊依序找尋 repository 是否存在檔案,取出第一個存在的檔案內容覆蓋工作目錄中指定檔案,達到回復檔案之功能。

git checkout 提交節點 檔案:檔案將回復至特定提交版本

當指定到特定提交節點時,Git 就會直接取回 repository 上該次提交版本中的檔案內容,直接覆蓋工作目錄中的指定檔案。有時候當把檔案改壞,就可以輸入 git checkout HEAD filename 將檔案回復到未修改前的樣貌。
 

簡單來驗證一下上述兩種操作方式

  1. 指定 boo.txt 回復到 odd5343 舊提交版本的檔案內容
  2. 因取出的檔案內容與 repository 最新 commit 的檔案存在差異,會自動加入 index (staged files) 

    ------- 這時候想要復原為 HEAD 版本 -------
     
  3. 若未指定版本,取到最新版本會是剛剛加入 index 的檔案喔!因此沒啥改變
  4. 若想復原為 HEAD 版本就要加入 HEAD提交節點 於 checkout 指令中
  5. 果然復原為原始檔案內容 (路徑後方呈現白色master表示無異動)

 

切換分支

git checkout 分支名稱:移動目前分支至指定分支上

移動分支時會先比較 tracked 檔案清單:

  • 檔案於目前分支有 tracked ,目標分支沒 tracked,會被刪除
  • 檔案於目前分支沒 tracked ,目標分支有 tracked,會被從 repository 取出
  • 至於目前及目標分支都沒 tracked 或列入 ignored 的檔案都不會被處理

至於針對共同 tracked 的檔案,會比較目前分支與目標分支於 repository 中檔案內容是否一致:

  • 如果不一致,會將目標分支檔案從 repository 取出,覆蓋工作目錄中的檔案。當目前存在未 commit 的異動時,為了避免目前異動的資料內容遺失,Git 會發出警告並中止切換;若想放棄異動,可以透過 git checkout -f 分支名稱 來強制複寫修改後的檔案
  • 如果是一致,就不會將目標分支檔案提出

以上看似合理,但請考慮一個情況,就是當目前分支與目標分支於 repository 中檔案A內容一致時,此時我們在目前分支中修改了檔案A且尚未 commit,當執行切換分支時,Git 比對 repository 中兩分支的檔案A是相同的,因此就不會從 repository 將檔案A取出來覆蓋工作目錄中的檔案,此舉將造成檔案A不會回到原始的狀態。

為了避免上述問題的產生,最好的方式就是要在切換分支時,將目前有異動的檔案提交到 repository 中;另外若是要確保切換分支後檔案內容是否與 repository 一致,可以執行 git status 來查看目前的檔案狀態是否無任何異動,若有則可考慮在切換回原本的分支,將異動檔案提交到 repository 中,或者執行 git checkout HEAD . 使用 repository 的檔案覆蓋工作目錄中的檔案。

 

建立新分支並切換目前分支至新分支上

git checkout -b 新分支名稱

所執行的動作可以分解為建立新分支,然後將目前分支切換至新分支上。

 

將目前分支 HEAD 移動至特定舊節點

git checkout 舊提交節點

執行後此時HEAD會移動到指定節點上,形成所謂的 detached HEAD 狀態,表示現在已經不屬於任合一個分支,如果此時進行修改提交(git add, git commit),則會產生一個沒有名稱的分支;若要回到原本分支時只要執行 git checkout 分支名稱 即可。

簡單來驗證一下

當執行 git checkout 0dd5343 後,此時 HEAD 就會移動到該節點上,如下所示。

我們可以看到執行後,訊息顯示目前為 detached HEAD 狀態,已不存在任何分支(從 master 變成 HEAD detached at 0dd5343);這時如果想要復原,直接執行 git checkout master 就可以切換回原本的 master 分支了。

 


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !