iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
1
Software Development

用樂高玩轉 GIT 版本控制系列 第 11

Day 11 - 切換 branch 與 還原目前工作區檔案:git checkout, restore, switch

  • 分享至 

  • xImage
  •  

今天的內容硬要跟樂高有關連,我大概會這樣說,當我們編輯樂高製作手冊,編輯到一半,還沒正式寫進手冊裡,但,我不想要目前編輯到一半的內容了,我該怎麼辦?但,我想不到寫手冊的時候,應該怎麼把寫到一半的內容塗掉...所以就不舉例了。

在 GIT 的 git checkout 指令

GIT 官方的手冊上是這樣說的:

git-checkout - Switch branches or restore working tree files

很明確的,git checkout 有兩個功能,一個是 branch, HASH 間的切換,另外一個則是工作區檔案的還原。

使用 git checkout 還原一個檔案

當編輯的檔案中,存在一些不小保留的原始碼,就可以使用 git checkout [path],如目前所在的目錄下有一個 apple.html 我想還原檔案到目前 HEAD 所代表的變更後內容,則我可以執行 git checkout apple.html

舉例來說,假設我的工作區域裡,目前編輯了兩個檔案,分別是 apple.html 及 banana.html,如下圖,可以看到狀態中有兩個檔案。

有兩個檔案有變更

當我執行 git checkout apple.html 後,畫面顯示「Updated 1 path from the index」,代表已經把 apple.html 這個檔案,還原到跟目前儲存庫所代表變更後的內容一樣了。

顯示更新一個檔案回儲存庫目前代表的狀態

這時候再使用 git status 查看,可以發現,也只剩下一個檔案有變更。

只剩下一個檔案有變更

還原全部檔案,使用 git checkout .

當我們要還原全部的檔案呢?這時候就可以使用 git checkout . 這個指令。如下圖,環境中依然有兩個檔案被變更。

有兩個檔案有變更

執行 git checkout . 之後,顯示有兩個檔案被還原。

有兩個檔案還原了

使用 git checkout 在分支中進行切換

以前兩天建立的 branch develop 來說,如果我要切換到 develop 這個 branch,我只需要執行 git checkout develop 指令,就可以把 HEAD 切換到 develop 所代表的儲存庫位置上。

而同樣的 git checkout [branch],還可以是 HASH Code 或 tag name。

使用 checkout 指令移動 HEAD 到分支

狀況題:如果 checkout 的檔案名稱跟分支(branch)名稱一樣呢?

首先,如同上面使用的儲存庫,我在 master 的分支上,新增一個檔案,名稱叫做develop,並且編輯一些內容,而後 commit 進儲存庫。接著我持續再編輯 develop 這個檔案。這時候我們的這個工作環境裡,存在一個分支名稱叫做 develop 的 branch,也同時存在名稱為 develop 的檔案。

這時候如果我執行 git checkout develop 這指令,會發生什麼事情呢?

  1. 狀況如下:

Git status 狀態

  1. 執行後結果:

執行後結果

執行後,提醒「本地有檔案變更,檔案名稱為 develop,請先處理這個檔案後再做 branch 的切換」,可以發現 GIT 會 先以 branch 為第一優先查找。

如果我就是要還原檔案怎麼辦?

在 GIT 2.23.0 之後,新增了兩個指令,分別是 git restore 以及 git switch 兩個指令就是為了分擔 git checkout 的兩個職責,讓原本還原檔案的工作讓 git restore 專職負責,而切換 branch 的工作則由 git switch 代替。

因此 上面提到的例子就簡單多了,同樣的情境只要使用 git restore develop 就可以完成還原檔案了。

還原後的畫面

加碼:在 SourceTree 這工具上,還原檔案可以怎麼做?

因為是工具列,所以如果有需要還原的檔案內容,我們也就只需要在畫面上選取也就足矣。同樣舉 apple.html 以及 banana.html 的例子,目前 apple.html 已經在舞台區(staged) 而 banana.html 還在工作區(unstaged)。

  1. 當選擇在舞台區的 apple.html 時,可以看到畫面右邊有一個 「unstage hunk」的按鈕,可以把這個 hunk 還原到工作區

還原到工作區

也可以選擇你想還原的行數,作 「unstage lines」就只會還原所選取的行。

把行還原到工作區

  1. 當選擇還在工具區的檔案 banana.html 可以看到兩個按鈕,左邊的是「stage hunk」也就是推進到舞台區,右邊的是 「Discard hunk」意思是,這整個變更都不要了,按下這個按鈕,你所做的變更也就都清空了。

放棄這個 hunk 的變更

也可以對要放棄的行直接做選取,這時候畫面會出現「stage line」及右邊的「Discard lines」。

放棄這個行的變更

總結:

GIT 在 2.23.0 之後提供了 git restore 以及 git switch 兩個指令,來區分開 git checkout 身上的兩個功能,「語意」上還蠻直覺的,在能夠升級到新版本 GIT 的朋友,可以考慮改使用這兩個指令。或許,這就是 Clean Code 常講的單一職責吧,讓一個指令只專注負責好一件事情。

在寫這篇的時候,突然想起 Day 10 提的 stash ,也是一個還原工作區檔案的方法,怎麼說呢?我只要透過 git stash 把目前工作的內容 push 進暫存,定期去 delete stash,一個層面上也是個「資源回收桶」的概念。

參考連結:


上一篇
Day 10 - 編輯到一半突然有其他事情插進來要先做,該怎麼辦?談 git stash
下一篇
Day 12 - 你手冊新增的部分不錯,我們合作吧!分支合體技 git merge
系列文
用樂高玩轉 GIT 版本控制30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
墨嗓
iT邦研究生 3 級 ‧ 2019-09-27 23:42:11

PeterLiao 昨天聊天提到的 Discard hunk 加碼~~

PeterLiao iT邦新手 4 級 ‧ 2019-09-28 12:22:23 檢舉

那天我想做的是 unstage 而不是 discard , 好險是在小檔案犯錯 ,永遠會記得 XD
謝謝墨嗓大大加碼~

我要留言

立即登入留言