← 上一章:【狀況題】等等,這行程式誰寫的? 下一章:【狀況題】剛才的 Commit 後悔了,想要拆掉重做… →
【狀況題】啊!不小心把檔案或目錄刪掉了…
貼心小提示
本章節用到的
rm
指令使用請小心,請不要在精神不好的時候使用,以免造成連 Git 都救不了你的悲劇。
人有失蹄馬有失手,總是有不小心或沒睡飽精神不好的時候。不管是有心或無心,在 Git 裡面如果不小心把檔案或目錄刪掉是救得回來的,這也是我們之所以使用版本控制系統最主要原因之一。這裡我先故意使用 rm
指令,把專案裡所有的 HTML 檔刪掉:
$ rm *.html
$ ls -al
total 8
drwxr-xr-x 6 eddie wheel 204 Aug 17 04:38 .
drwxrwxrwt 65 root wheel 2210 Aug 17 03:38 ..
drwxr-xr-x 15 eddie wheel 510 Aug 17 04:44 .git
-rw-r--r-- 1 eddie wheel 232 Aug 16 17:14 .gitignore
drwxr-xr-x 3 eddie wheel 102 Aug 16 16:45 config
drwxr-xr-x 2 eddie wheel 68 Aug 16 17:19 images
的確可以看到所有的 HTML 檔都不見了。接著看一下目前的 Git 狀態:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: cinderella.html
deleted: index.html
deleted: welcome.html
deleted: world.html
no changes added to commit (use "git add" and/or "git commit -a")
看得出來目前這四個檔案都是處於被刪除(deleted
)的狀態。
別擔心,這時如果要把 cinderella.html
救回來,可以使用 git checkout
指令:
$ git checkout cinderella.html
看一下檔案列表:
$ ls -al
total 8
drwxr-xr-x 7 eddie wheel 238 Aug 17 04:46 .
drwxrwxrwt 65 root wheel 2210 Aug 17 04:45 ..
drwxr-xr-x 15 eddie wheel 510 Aug 17 04:46 .git
-rw-r--r-- 1 eddie wheel 232 Aug 16 17:14 .gitignore
-rw-r--r-- 1 eddie wheel 0 Aug 17 04:46 cinderella.html
drwxr-xr-x 3 eddie wheel 102 Aug 16 16:45 config
drwxr-xr-x 2 eddie wheel 68 Aug 16 17:19 images
那個檔案回來了!如果想一口氣把所有被刪掉的檔案救回來:
$ git checkout .
看一下檔案列表:
$ ls -al
total 24
drwxr-xr-x 10 eddie wheel 340 Aug 17 05:34 .
drwxrwxrwt 65 root wheel 2210 Aug 17 04:45 ..
drwxr-xr-x 15 eddie wheel 510 Aug 17 05:34 .git
-rw-r--r-- 1 eddie wheel 232 Aug 16 17:14 .gitignore
-rw-r--r-- 1 eddie wheel 0 Aug 17 04:46 cinderella.html
drwxr-xr-x 3 eddie wheel 102 Aug 16 16:45 config
drwxr-xr-x 2 eddie wheel 68 Aug 16 17:19 images
-rw-r--r-- 1 eddie wheel 161 Aug 17 05:34 index.html
-rw-r--r-- 1 eddie wheel 27 Aug 17 05:34 welcome.html
-rw-r--r-- 1 eddie wheel 0 Aug 17 05:34 world.html
你可以發現,不只六師弟回來了,剛剛被刪掉的所有檔案也都回來了。
使用 SourceTree 的話,這些被刪除的檔案前面會被標記一個減號。可以選取一個或多個檔案後,按滑鼠右鍵選擇「Reset…」功能:
然後會跳出一個確認對話框,問你是否確認:
按下 OK 鈕之後,剛剛刪除的那些檔案就救回來了。
這個技巧不只用在刪除的檔案可以救回來,當你修改某個檔案但後悔了,也可以用這個指令把檔案回復成它上一次 Commit 的狀態。
再怎麼樣都救得回來嗎?
也不能這麼說,因為整個 Git 的紀錄都是放在根目錄的 .git
目錄裡,所以如果這個目錄被刪了,也就是表示歷史紀錄也被刪了,那就沒得救了。
【冷知識】Git 是去哪裡把檔案救回來的?
其實是使用《火影忍者》忍術「穢土轉生」把檔案救回來的!
開玩笑的,當然不是用忍術。這裡用的 git checkout
指令,在後面提到關於分支的時候也會再度出現。當使用 git checkout 分支名稱
的時候,Git 會切換到指定的分支,但如果後面接的是檔名或路徑,Git 則不會切換分支,而是把檔案從 .git
目錄裡拉一份到目前的工作目錄。
更精準的來說,這個指令會把暫存區(Staging Area)裡的內容或檔案,拿來覆蓋工作目錄(Working Directory)的內容或檔案。所以當在上面執行 git checkout welcome.html
或 git checkout .
的時候,它會把 welcome.html 這個檔案,或是當下目錄所有檔案回復到上一次 Commit 的狀態。
如果在執行這個指令的時候這樣做多加了一個參數:
$ git checkout HEAD~2 welcome.html
這樣就會拿距離現在兩個版本以前的那個 welcome.html 檔案來覆蓋現在的工作目錄裡的 welcome.html 檔案,但要注意的是,這同時也會更新暫存區的狀態喔。
如果能理解上面這個指令的意思:
$ git checkout HEAD~2 .
這個指令的意思就是「拿距離現在兩個版本以前的檔案來覆蓋現在工作目錄的檔案,同時也更新暫存區裡的狀態」。
Comments