Git 取出特定時間點檔案的內容
最近在工作上,剛好碰到一個情境:我想要在不改變 HEAD 的情況下,取出之前某個時間點(也就是 commit)的檔案內容,應該要怎麼做?
通常直覺應該是直接 checkout 到那個時間點上,但這樣會改變 HEAD 變成斷頭(detached HEAD)狀態,而且當下我還有其他未 commit 但已經 add 的檔案,不想破壞目前的狀態避免開發的東西壞掉。
搜尋一下,馬上就找到一篇文章在討論,實際測試也真的有用。而且還發現了新東西,故寫了這篇文章做點小筆記。
解法
checkout
越早就開始使用 git 或看到比較早之前教學文的人,一定對 git checkout
這個指令相當熟悉。一如前言所提到的,git-checkout
就像是時光機一樣可以在 commit 之間穿梭,也能從 stage 中取出東西。而這次,這個指令將再次發揮他的萬能拯救我們:
1 |
|
<>
就是依照自己需求填入的部分。
restore
git-restore
是 版本 2.23.0 開始新加上的指令(git-switch
也是此次推出),我們都知道 checkout 非常萬能,但相對的他背負太多東西了,所以從 2.23.0 開始新增剛剛提及的兩個新指令分別取代部分 checkout 的功能(但為了向下相容,checkout 能可使用。故可以看到有些專案仍使用 checkout。)。
細節在此不多談,既然是要取代 checkout,那剛剛的功能也要能處理才對?沒錯,來講一下如果是 restore 該怎麼做到這件事:
1 |
|
指令中的 --source
旗標有縮寫,所以也可以寫成:
1 |
|
神秘的--
看到這邊,我自己對於指令中的 --
非常好奇,那個是做什麼用的?往下面的答案下的留言(沒有答案有解釋,都是在留言中找到的)發現有人提到:
With git, if you’re unsure, always prefix all files and directories with the special argument
--
.
--
is not a git command and not special to git. It is a bash built-in to signify the end of command options. You can use it with many other bash commands too.
No,
--
is not a builtin special word in bash. But it is a common convention supported by many commandline parsers and used by many CLIs, including git.
嗯……就算用了翻譯也不是很明白意思,不過可以看出這個不是 bash 內建的語法。繼續看看其他留言:
The
--
is not only a git convention, but something you find in various places in on the *nix commandline.rm -- -f
(remove a file named-f
) seems to be the canonical example.
到了這邊總算明白意思了,這個 --
是分隔指令和參數用的,用意在告訴程式說「在 --
之後的東西是我的參數」而且並非內建或是 git 獨有的,他是一種慣例的表達方式。所以這個表達方式有沒有用,要看該程式是否有支援。