← 上一章:【狀況題】手邊的工作做到一半,臨時要切換到別的任務 下一章:【狀況題】如果你只想要某個分支的某幾個 Commit? →
【狀況題】不小心把帳號密碼放在 Git 裡了,想把它刪掉…
你不小心把帳號密碼寫在某次的 Commit 裡,而且已經 Push 出去了…
如果已經 Push 出去,請不要先想要怎麼用 Git 來解決,請先直接改密碼再說!
改完密碼了嗎?那接下來我們再來看看怎麼解決這件事吧。
砍掉重練大法
這招是屬於「逃避雖然可恥但是有用」的做法,把因為所有的 Commit 紀錄都在 .git
目錄裡,所以可以這樣:
- 把 .git 目錄刪掉。
- 把那個密碼檔刪掉或修掉。
- 重新 Commit。
不要以為我是在開玩笑,這也是一招,而且是比較不需要什麼技術的招式,缺點就是之前的 Commit 紀錄都不見了。所以這個專案如果只有你自己一個人做,而且也不在乎之前的 Commit 紀錄的話,這也是一個選擇。
使用 filter-branch
指令
如果你不想使用砍掉重練大法,另一個選項就是使用 Git 的 filter-branch
指令。假設目前的 Commit 紀錄是這樣:
在這個例子裡,我從第二個 Commit(382a2a5
)開始就已經把資料庫的密碼加進去了。
假設我想要把 config/database.yml
這個檔案從每個 Commit 裡把它拿掉,比較直覺但稍微比較辛苦的做法是使用 Rebase 指令,然後一個一個 Commit 去編輯。Git 有一個叫做 filter-branch
的指令,這個指令不算太常見,但它可以一次大量的修改 Commit。
$ git filter-branch --tree-filter "rm -f config/database.yml"
Rewrite db3bbec63301d1c638e828c9a38a29314c8a0c44 (9/10) (1 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten
說明:
filter-branch
這個指令可以讓你根據不同的 filter,一個一個 Commit 的來處理它。- 這裡使用了
--tree-filter
這個 filter,它可以讓你在 Checkout 到每個 Commit 的時候執行你指定的指令,執行完後再自動幫你重新再 Commit。以上面這個例子來說,便是執行「強制刪除config/database.yml
檔案」這個指令。 - 因為刪除了某個檔案,所以在那之後的 Commit 全部都會重新計算,也就是說等於產生一份新的歷史紀錄了。
東西一旦加到 Git 裡,真的要把它刪掉其實沒那麼容易,我們在下一章「【冷知識】怎麼樣把檔案真正的從 Git 裡移掉?」章節會再做更多的說明。
啊!我又後悔了,怎麼回復剛剛 filter-branch 造成的結果?
使用 Git 的好處,就是後悔隨時可以重來。其實在進行 filter-branch
指令的時候,Git 會幫你把之前的狀態備份一份在 .git/refs/original/refs/heads
這個目錄裡(其實說是備份,也只是備份開始進行 filter-branch
之前的那個 HEAD 的 SHA-1 值而已)。所以你可以從這個檔案把 SHA-1 值找出來然後再 hard Reset 回去,或是直接這樣也可以:
$ git reset refs/original/refs/heads/master --hard
HEAD is now at db3bbec add fish
這樣就都回來了。
如果已經推出去了…
老實說,推出去的東西就跟潑出去的水一樣收不回來,你能做的就是使用 git push -f
指令,重新強制推一份你剛剛 filter-branch
過的 Commit 上去。在「Push 上傳到 GitHub」章節會有更多關於 Push 相關的介紹。
← 上一章:【狀況題】手邊的工作做到一半,臨時要切換到別的任務 下一章:【狀況題】如果你只想要某個分支的某幾個 Commit? →
Comments