分類

展開全部 | 收合全部

分類

展開全部 | 收合全部

【Git 備份還原 #1】git reset, git checkout | 萬能又危險的 git 復原神器?! 不論怎麼樣的修改都可以還原的版本方式!

前言

這其實也是個 git 的面試經典考題,git reset 與 git checkout 都可以幫我們移動到某一個版本紀錄 (commit)上,
那他們兩個有什麼差別呢?

沒事請用 git checkout,git reset 很好用,但也很危險

版本紀錄本身是有「時間相依的」,因此我們不能夠任意的修改過去與未來的因果關係,

例如:因為下雨,才撐傘,
因為撐傘,傘才被風吹壞。

我們可以得到:下雨 -> 撐傘 -> 傘壞

然後我們不可以把歷史中的過程進行修改,變成「下雨 -> 傘壞」,整個因果都亂了,
git reset 的危險類似這樣的概念,因為「雲端存在這樣的歷史」,而「本地的歷史已經亂了」,導致無法合併 (不能 push) 的狀態

如果有讀過我的其他 git 筆記,我的老師一直都有在強調一個觀念,
沒事不要「亂 push 上雲」,除非你很確定現在的版本順序非常正確
因為「在 Push 之前」,我們可以輕鬆的用 reset 搞定上面的問題,但碰到的「remote 歷史不一致問題」
就會變超級麻煩… 甚至我都有點懶得慢慢的處理這種問題

圖解

為了方便理解,這裡我們把 commit id 替換成時間,更突顯出時間軸的概念

我們可以從下面看出 git reset 與 git checkout 從 11:00 回到 10:00 時的差別

  • commit 當下最新的狀態

我們可以注意我們的 HEAD 與 master 都在最新的狀態

git checkout

主要有兩種用法 commit 與 branch,但都是讓目前的工作目錄回到指定的狀態,
branch 會是 branch 目前的 head,
而我自己最常用的是去指定 commit id。

小技巧:commit id 很長還要慢慢打不好用?其實可以不用打完,打前幾個字就會智慧的自動判斷了。
如果前幾個字有出現重複,他也會提示你,通常再多打幾個字就可以確定那「唯一的 commit id」

git checkout <branch name>
git checkout <commit id>
  • checkout 後,我們暫時移動到過去的版本

這是我們最經常用的操作

留下了 master,我們可以當作一個旗標,
我們之後想回去的時候,只需要 git checkout master 就能隨時回去,
因此這個旗子非常重要,不能隨便亂改,
不然我們可能就回不去了!!

git reset

git reset –soft

簡單來說,就是回到 git add 後、git commit 前的狀態,
也因此,最新的 master 會被移動,我們沒辦法透過 git checkout master 回去!
「事實上,使用 git reset 也沒必要回去了,我們用 git reset 就是要消除最新的 commit」

git reset (–mixed): default

簡單來說,就是回到 git add 前的狀態,
除了不要最新的 commit,連 modified 的狀態也回復了

git reset –hard

個人也非常常用的功能,直接把檔案完全還原成自己想要的「當時狀態」

完全回到某個版本的狀態,連檔案也修改,
然而這個指令也是最危險的,建議在進行此操作的過程中,

完全控制在 local 使用,不要牽扯到 remote

注意到了嗎? 「如果是 reset,11:00 的紀錄會因為時空回溯而消失!!!

你應該會想問,那如果 reset 我還回的去嗎? 可以,但前提是你必須要有他的 commit id,
這可以用 git reflog 查
可是既然都要回去了,為何不當初就用 git checkout 移動就好呢?

checkout, reset 兩者都有必要性

上面我們似乎講了 reset 很不好、很危險,那他的必要性是什麼?
我們偶爾會做錯事情 (不要以為你很聰明,就不會做錯事XDD)

像是不小心把「很大的檔案」加到了 commit 裡面,導致後續同步時變超久
這時候這種「黑歷史」,何必讓他留在時間軸上呢?

git reset 就是專門砍「黑歷史」的工具,而如果在 local 的資料夾使用得宜,
其實會是個非常好用管理版本工具,「砍掉任何不是重要里程碑的 commit、砍黑歷史」,都非常好用!

因此如果我們想要,我們甚至可以做到:

我覺得 10:00 的紀錄沒有價值,或者 11:00 更具有代表性,
也能代表 10:00,因此 10:00 沒必要成為一個版本

就可以透過 reset 改成這樣:

但一樣的老話,這種操作,在 local 還非常容易處理,一但 push 到了 remote,
就請先放棄吧,乖乖的用 checkout 處理讓黑歷史留在那邊。(除非太嚴重,但處理也非常麻煩)
我們會因為 remote 可能會產生「時空倒流的行為」,必須回到「更早的時間點」,去「重新理順時空的因果」。

reference

⭐Git 相關文章整理⭐:
1.【Git】1 – 簡單開始學 git,認識 git 與基本觀念、心態建立,初學者學習 git 碰壁的原因 與 建議學習 git 的方式
2.【Git】git 初學者向 – 最簡單直白的理解 git 基本介紹 與 基本使用 (內有範例程式碼) 總整理 大全
3.【Git】git ignore 設定方法筆記,在 git add 時 固定不要特定檔案 git add remove
⭐【喜歡我的文章嗎? 歡迎幫我按讚~ 讓基金會請創作者喝一杯咖啡!
如果喜歡我的文章,請幫我在下方【按五下Like】 (Google, Facebook 免註冊),會由 「LikeCoin」 贊助作者鼓勵繼續創作,讀者們「只需幫忙按讚,完全不用出錢」哦!

likecoin-steps
Howard Weng
Howard Weng

我是 Howard Weng,很多人叫我嗡嗡。這個網站放了我的各種筆記。希望這些筆記也能順便幫助到有需要的人們!如果文章有幫助到你的話,歡迎幫我點讚哦!
另外,因為定位是「個人的隨手筆記」,有些文章內容「⚠️可能我理解有誤⚠️」或「?只寫到一半?」,如果有發現這樣的情況,歡迎在該文章的最下面留言提醒我!我會儘快修正或補上!感謝大家的建議與幫忙,讓網站能變得更好?

文章: 889

★留個言吧!內容有誤或想要補充也歡迎與我討論!