Git本地操作進階之版本回退,撤銷修改與文件刪除全攻略
前言
在掌握Git本地倉庫的基礎(chǔ)操作后,“如何修正錯誤提交”“怎樣找回誤刪文件”“版本回退的風(fēng)險與應(yīng)對”成為開發(fā)者進階的關(guān)鍵課題。代碼開發(fā)中,誤改配置、提交冗余文件、刪除核心代碼等情況難以避免,而Git提供的版本回退、撤銷修改、文件刪除機制,正是解決這些問題的 “安全網(wǎng)” 。本文將聚焦這些進階操作,拆解其原理、場景與實操細節(jié),幫你在代碼出現(xiàn)偏差時,精準、安全地將版本拉回正軌。
一. Git關(guān)鍵能力:版本回退與撤銷修改
開發(fā)階段中,難免會出現(xiàn)代碼寫錯,提交誤操作等情況,Git提供了完善達到版本回退和撤銷機制,可根據(jù)修改所處階段靈活處理。
1.1 版本回退
通過 git reset 命令實現(xiàn)版本回退,核心是通過 commit id 或 HEAD 指針定位目標版本,命令格式為:git reset 【--soft | --mixed | --hard】【HEAD】
關(guān)鍵參數(shù)說明:
| 參數(shù) | 作用 | 風(fēng)險程度 |
|---|---|---|
--mixed | 默認參數(shù),僅暫存區(qū)回退到指定版本,工作區(qū)內(nèi)容保持不變 | 低 |
--soft | 僅版本庫回退,暫存區(qū)和工作區(qū)內(nèi)容均不改變 | 低 |
--hard | 暫存區(qū)、工作區(qū)、版本庫均回退到指定版本 | 高(工作區(qū)未提交代碼會丟失) |
HEAD 說明:
- 可直接寫成 commit id,表?指定退回的版本
- HEAD 表示當前版本
- HEAD^ 上一個版本
- HEAD^^ 上上一個版本
- 以此類推…
可以使用 ?數(shù)字表示:
- HEAD~0 表示當前版本
- HEAD~1 上一個版本
- HEAD^2 上上一個版本
- 以此類推…
實際使用:
為了便于表述,方便測試回退功能,我們需要先做一下準備工作:更新3個版本的ReadMe,并分別進行3次提交,如下所示:
# 第一次修改提交 [root@VM-4-4-centos gitcode]# echo "hello version1" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 [root@VM-4-4-centos gitcode]# git add ReadMe [root@VM-4-4-centos gitcode]# git commit -m "add version1" [master 40bc6e6] add version1 1 file changed, 1 insertion(+) # 第二次修改提交 [root@VM-4-4-centos gitcode]# echo "hello version2" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 [root@VM-4-4-centos gitcode]# git add ReadMe [root@VM-4-4-centos gitcode]# git commit -m "add version2" [master 1a083cf] add version2 1 file changed, 1 insertion(+) # 第三次修改提交 [root@VM-4-4-centos gitcode]# echo "hello version3" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3 [root@VM-4-4-centos gitcode]# git add ReadMe [root@VM-4-4-centos gitcode]# git commit -m "add version3" [master b592a38] add version3 1 file changed, 1 insertion(+) # 查看歷史記錄 [root@VM-4-4-centos gitcode]# git log --pretty=oneline b592a387a176cfb00c56cd3cbc1d3faca9ba2cee add version3 1a083cf93e6f21ba0bf5419f32125875aa787255 add version2 40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1 …… #之前的一些這里就不放出來了
現(xiàn)在,如果我們提交完 version3 后,發(fā)現(xiàn) version3 編寫錯誤,想退回到 version2 ,重新基于 version2 開始編寫。由于我們這里希望的是將工作區(qū)的內(nèi)容也回退到 version2 版本,所以需要用 --hard 參數(shù),示例如下:
[root@VM-4-4-centos gitcode]# git log --pretty=oneline b592a387a176cfb00c56cd3cbc1d3faca9ba2cee add version3 1a083cf93e6f21ba0bf5419f32125875aa787255 add version2 40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1 ………… # 指定 version2 的對應(yīng)版本號,回退到這個版本 [root@VM-4-4-centos gitcode]# git reset --hard 1a083cf93e6f21ba0bf5419f32125875aa787255 HEAD is now at 1a083cf add version2 [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2
我們可以發(fā)現(xiàn),此時 ReadMe 文件的內(nèi)容,已經(jīng)回退到 version2 了!,當前,我們再次使用 git log 查看一下提交日志,會發(fā)現(xiàn) HEAD 指向了version2 ,如下所示:
[root@VM-4-4-centos gitcode]# git log --pretty=oneline --decorate 1a083cf93e6f21ba0bf5419f32125875aa787255 (HEAD, master) add version2 40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1 …………
到這里一般回退功能就演示完畢了,但是如果我后悔了,想再回到 version3 怎么辦?我們可以繼續(xù)使用 git reset 命令,回退到 version3 版本 ,但是我們必須拿到 version3 的 commit id 去指定回退版本。
但是我們看到了 git log 并不能打印出 version3 的 commit id ,運氣好的話我們可以從終端上去找找之前的記錄,運氣不好的話 commit id 就已經(jīng)被我們搞丟了~~
值得一提的是 Git 還提供了一個 git reflog 命令能補救一下,該命令用來記錄本地的每一次指令。
[root@VM-4-4-centos gitcode]# git reflog
1a083cf HEAD@{0}: reset: moving to 1a083cf93e6f21ba0bf5419f32125875aa7
b592a38 HEAD@{1}: commit: add version3
1a083cf HEAD@{2}: commit: add version2
40bc6e6 HEAD@{3}: commit: add version1
eb85e67 HEAD@{4}: commit: delete
54cffd0 HEAD@{5}: commit: add 3 file3
1e3f5b8 HEAD@{6}: commit: commit my first file
fcce812 HEAD@{7}: commit (initial): add first file
(END)
這樣,你就可以很方便的找到你的所有的操作記錄了,但是 b592a38 這個是啥東西?這個是 version3 的 commit id 的部分。Git 版本回退的時候,也可以使用部分的 commit id 來代表目標版本。示例如下:
# 回退到 version3 [root@VM-4-4-centos gitcode]# git reset --hard b592a38 HEAD is now at b592a38 add version3 # 查看工作區(qū) [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3 # 查看 log [root@VM-4-4-centos gitcode]# git log --pretty=oneline --decorate b592a387a176cfb00c56cd3cbc1d3faca9ba2cee (HEAD, master) add version3 1a083cf93e6f21ba0bf5419f32125875aa787255 add version2 40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1 …………
可往往是理想很豐滿,現(xiàn)實很骨感。在實際開發(fā)中,由于長時間的開發(fā),很可能會導(dǎo)致 commit id 早就找不到了,可突然某一天,我又想回到 version3 ,那該如何操作呢?貌似現(xiàn)在是不可能了~
補充說明:
Git 版本的回退速度特別快,因為 Git 在內(nèi)部有個指向當前分支(此處是master)的HEAD指針,refs/heads/master 文件里保存當前 master 分支的最新的 commit id 。當我們在回退版本的時候。Git 僅僅是給refs/heads/master 中存儲一個特定的version ,可以簡單理解為如下示意圖:

1.2 撤銷修改
根據(jù)修改所處階段(工作區(qū) / 暫存區(qū)),選擇不同的撤銷命令:
場景 1:修改僅在工作區(qū),未執(zhí)行g(shù)it add
使用 git checkout -- [file](這個 - - 很重要,一旦省略會變成別的意思) 丟棄工作區(qū)修改,恢復(fù)到最近一次git add或git commit時的狀態(tài):
友情提示:千萬不要想著用什么 git diff xxx 找到差異去手動刪除,那要是改的地方多得刪多久啊,這不得累麻了
# 向 ReadMe 新增一行內(nèi)容 [root@VM-4-4-centos gitcode]# echo "It is shift" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3 It is shift # 恢復(fù)到上一次 add 或 commit [root@VM-4-4-centos gitcode]# git checkout -- ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3
場景 2:修改已執(zhí)行g(shù)it add到暫存區(qū),未commit
add 后還是保存到了暫存區(qū),怎么撤銷呢?
# 向 ReadMe 新增一行內(nèi)容 [root@VM-4-4-centos gitcode]# echo "It is shit" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3 It is shit # add 存入暫存區(qū) [root@VM-4-4-centos gitcode]# git add ReadMe # git status 查看一下 [root@VM-4-4-centos gitcode]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: ReadMe #
那我們該怎么做呢?我們來回憶一下之前學(xué)過的 git reset 回退命令。該命令如果使用 --mixed 參數(shù),可以將暫存區(qū)的內(nèi)容回退到指定的版本內(nèi)容,但工作區(qū)文件保持不變,我們再接著用上面場景一的方法解決一下不就好了。
總的來說就是:先將暫存區(qū)修改撤銷到工作區(qū),再丟棄工作區(qū)修改:
# 先將暫存區(qū)修改撤銷到工作區(qū),--mixed 是默認參數(shù),可以省略 [root@VM-4-4-centos gitcode]# git reset HEAD ReadMe Unstaged changes after reset: M ReadMe # git status 查看一下 [root@VM-4-4-centos gitcode]# git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: ReadMe # no changes added to commit (use "git add" and/or "git commit -a") # 類似于場景一,丟棄工作區(qū)的修改 [root@VM-4-4-centos gitcode]# git checkout -- ReadMe [root@VM-4-4-centos gitcode]# git status # On branch master nothing to commit, working directory clean [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3
成功恢復(fù)了?。?!
場景 3:修改已commit到版本庫(未推送到遠程)
直接通過 git reset --hard 回退到上一個版本即可。
注意:若已推送(push)到遠程倉庫,此操作會導(dǎo)致本地與遠程版本不一致,需謹慎,這個遠程倉庫我們在后面會講的。
# 向 ReadMe 中新增一行內(nèi)容 [root@VM-4-4-centos gitcode]# echo "I like coding" >> ReadMe [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3 I like coding # 添加 + 提交 [root@VM-4-4-centos gitcode]# git add ReadMe [root@VM-4-4-centos gitcode]# git commit -m "test quash" [master 1a0a253] test quash 1 file changed, 1 insertion(+) # 回退到上一個版本 [root@VM-4-4-centos gitcode]# git reset --hard HEAD^ HEAD is now at b592a38 add version3 [root@VM-4-4-centos gitcode]# cat ReadMe hello Lotso hello version1 hello version2 hello version3
二. Git 文件刪除:徹底刪除與誤刪恢復(fù)
在 Git 中,刪除文件也是一種 “修改操作”,需根據(jù)需求選擇 “徹底刪除” 或 “恢復(fù)誤刪文件”:
2.1 誤刪工作區(qū)文件,需恢復(fù)
[root@VM-4-4-centos gitcode]# ls file1 ReadMe [root@VM-4-4-centos gitcode]# rm file1 rm: remove regular empty file ‘file1'? y
直接這樣刪除其實是沒用的,反而徒增煩惱,git status 命令會立刻告訴你那些文件被刪除了;
[root@VM-4-4-centos gitcode]# 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: file1 # no changes added to commit (use "git add" and/or "git commit -a")
此時,工作區(qū)就和版本庫不太一樣了,要刪文件,目前除了要刪工作區(qū)的文件以外,還要清除版本庫的我文件。當然,我們這里如果是誤刪,可以直接使用 git checkout -- file 來進行恢復(fù),之前講過(刪除也是修改)。
[root@VM-4-4-centos gitcode]# ls ReadMe [root@VM-4-4-centos gitcode]# git checkout -- file1 [root@VM-4-4-centos gitcode]# ls file1 ReadMe
2.2 確認刪除文件,同步到版本庫
這里想要恢復(fù)也是可以的哈,上面也講到過的。
# 從工作區(qū)和暫存區(qū)同時刪除file1 [root@VM-4-4-centos gitcode]# git rm file1 rm 'file1' [root@VM-4-4-centos gitcode]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: file1 # # 提交刪除操作到版本庫 [root@VM-4-4-centos gitcode]# git commit -m "deleted file1" [master c213450] deleted file1 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 file1 [root@VM-4-4-centos gitcode]# git status # On branch master nothing to commit, working directory clean
到此這篇關(guān)于Git本地操作進階之版本回退,撤銷修改與文件刪除全攻略的文章就介紹到這了,更多相關(guān)Git本地操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VSCode 安裝 Copilot 詳細過程和實例代碼(最新推薦)
Copilot 作為一款 AI 輔助編程工具,可以極大地提高開發(fā)效率,讓編程變得更加輕松愉快,在實際開發(fā)過程中,我們要注意審查和測試生成的代碼,確保其符合項目需求和標準,這篇文章主要介紹了VSCode 安裝 Copilot 詳細過程和實例,需要的朋友可以參考下2024-05-05

