git checkout 介紹(switch、restore)

前言

在搜尋 Git 相關資料時發現, git checkout 要做的事情真的好多啊!很多發問平台上也有不少被這個指令的功能弄到很混淆的人,甚至 Git 官方也新出了兩個指令 git switchgit restore 來拆分 git checkout 的工作。

git checkout

Switch branches or restore working tree files.

先看看 Git 的官方說明,很明確的說出 git checkout 可以切換分支和還原檔案內容。但可能是想要讓指令工作單一化,或是讓使用者在使用上較直覺及不易混淆, Git 官方於 2019 年 2.23.0 Release Notes 釋出的兩個指令 git switchgit restore 來拆分這兩個功能。

接下來會直接針對兩個新指令做介紹,目前使用上覺得新指令比較直覺,如果跟我一樣還在學習指令的階段,建議可以學習新指令來使用。但如果還是習慣 git checkout 也沒關係,這個指令仍可以繼續使用,沒有被 Git 棄用。

接下來針對 git switchgit restore 的說明也會一併提供 git checkout 的指令,只要擇一使用即可。

git switch

git switch 指令主要的工作是在分支間切換,或在 commit hash 間切換。

切換分支

切換分支時, Git 會把 HEAD 指標指向目標分支,此時檔案將呈現分支指標的版本。

1
2
git switch <branch-name>
git checkout <branch-name>

查看指定提交版本

git switch 可以在提供指定提交版本的 commit hash 後,將 HEAD 指標移向該 commit 上。

1
2
3
# 直接指定查看某的提交版本
git switch -d <commit-hash> # (-d for --detach)
git checkout <commit-hash>

除了直接提供 commit hash 的方法外,也可以指定「相對於 HEAD 指標」的版本。這種方式會將 HEAD 指標以當下位置為基準進行移動。

1
2
3
# 移動到 HEAD 的前一個 commit
git switch -d HEAD~1 # (-d for --detach)
git checkout HEAD~1

通常情況下 HEAD 都會指向分支,如果使用以上指令讓 HEAD 指向特定的 commit (也就是指向非分支指標),則會發生 Detached HEAD 。 Detached HEAD 訊息只是作為提醒,
表示目前 HEAD 不指向任何一個分支。但仍然可以進行檔案瀏覽、編輯、提交及建立新的分支。在 Detached HEAD 的狀態下如果不新建分支就直接提交 commit,因為該提交不在任一分支上,日後可能不易查找。如果想離開 Detached HEAD 狀態,除了直接切換到指定分支外,也可以使用以下指令回到最近一次操作的分支:

1
git switch -

新建並切換分支

git switch 也可以用來新建分支。該指令會從 HEAD 指向的 commit 長出新的分支,並切換到該分支上。

需要特別注意的是,在新建分支時,使用 git switch 和使用 git checkout 所使用的參數不一樣。

1
2
git switch -c <branch-name>      #(-c for --create)
git checkout -b <branch-name>

git restore

git restore 的功能是讓檔案內容恢復到指定的版本。

檔案內容回復到指定版本

這個操作並不會對提交歷史有任何的影響,只是讓檔案的「內容」回復到較早之前的版本,也就是「棄用」新編輯的內容。在 git add 之前,可以不斷地重複使用以下指令來讓內容變成之前版本的樣子。

1
2
3
4
5
6
7
8
# 讓檔案回到最近一次 HEAD 指向版本的樣子
git restore <files>
git checkout HEAD <files>
git checkout -- <files>

# 讓檔案回到指定 commit 版本的樣子(用 HEAD 的相對位置來指定)
git restore -s HEAD~2 <files> # (-s for --source)
git checkout HEAD~2 <files>

檔案從 staged 清單移除

如果使用 git add 將檔案 staged 之後,發現這不是我要提交的樣子,希望將檔案從 staged 清單移出,那就可以使用以下指令:

1
git restore -S <files>    # (-S for --staged)

文章內容如有錯誤,歡迎留言討論!


本 Blog 上的所有文章除特别聲明外,均採用 CC BY-SA 4.0 協議 ,轉載請註明出處!