作為版本控制管理器,Git應當具備版本回退等一系列功能——它的應用場景也很常見,當你在工作區開發時,忽然發現:怎么我這版本寫的代碼還不如上一版本好?這時,版本回退功能就派上用場了。
一.版本回退
1.概覽
首先我們先明確版本回退的指令
git reset [--soft]|--mixed|[--hard]? [HEAD]
我們來一一解釋這幾個選項對應的作用。
ReadMe | 工作區 | 暫存區 | 版本庫 | 選項 |
git world | git world | git world | git | --soft |
git world | git | git | --mixed | |
git | git | git | --hard |
1.--soft:僅回退版本庫的內容
2.--mixed:回退暫存區和版本庫內容,是默認選項
3.--hard:將所有區域內容全部回退,有可能會覆蓋當前工作區的內容,建議謹慎使用。
2.回退工作流
1.git log——查看日志。若要執行回退,首先要明確回退到哪個版本。
wujiahao@VM-12-14-ubuntu:~/gitcode$ git log --pretty=oneline
18812885f304b7ba2baa67a109a2762ebb6f85c3 (HEAD -> master) add some files
f5aa7498c931ae9bc6cf0edfa400f7ceb28816a9 add first word
2.git reset ——執行回退,選項后面跟上commitID即可。例如這里回退到 add some files。
wujiahao@VM-12-14-ubuntu:~/gitcode$ git reset --hard 18812885f304b7ba2baa67a109a2762ebb6f85c3
HEAD is now at 1881288 add some files#現在的效果
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
3.git reflog——如果后悔回退怎么辦?可以查找本地所有reset操作的日志,回退到其他想要的版本(繼續執行git reset即可)
wujiahao@VM-12-14-ubuntu:~/gitcode$ git reflog
1881288 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
d6a7559 HEAD@{1}: commit: Modify ReadMe Third
1881288 (HEAD -> master) HEAD@{2}: reset: moving to 18812885f304b7ba2baa67a109a2762ebb6f85c3
1881288 (HEAD -> master) HEAD@{3}: commit: add some files
f5aa749 HEAD@{4}: commit (initial): add first word
3.回退的原理
我們在執行版本回退時,會發現其執行速度非常快。那么它的原理是什么呢?
根據commitID直接修改HEAD指針指向的git對象
二.撤銷修改
1.概覽
撤銷修改的情況可以大概分為以下幾類:
情況 | 執行操作 |
僅修改工作區 | git checkout -- filename |
執行了add,但沒有commit到版本庫 | 1.git reset --hard filename 2.git reset --mixed filename git checkout -- filename |
已經commit到版本庫,但沒有執行push到遠程倉庫 | git reset --hard |
接下來一一進行詳解。
2.詳解
1.僅修改工作區
例如這里我們對ReadMe寫入xxx code
wujiahao@VM-12-14-ubuntu:~/gitcode$ vim ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
xxx code
怎樣回退到之前的版本?我們當然可以選擇用vim編輯器等修改,但是修改的部分越多越復雜,這種方法越不實用。因此我們使用以下方法:
git checkout -- filename
wujiahao@VM-12-14-ubuntu:~/gitcode$ git checkout -- ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
2.執行了add,但沒有commit到版本庫
我們寫入this is the second change并執行add
wujiahao@VM-12-14-ubuntu:~/gitcode$ vim ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
this is the second change
wujiahao@VM-12-14-ubuntu:~/gitcode$ git add ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ git status
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)modified: ReadMeUntracked files:(use "git add <file>..." to include in what will be committed)file5
git status
查看當前git狀態,發現暫存區有文件被修改(ReadMe)
首先這里有兩種解決辦法,一種直接reset –hard,另一種是reset –mixed(默認選項),默認回退版本庫和暫存區,相當于回到了第一種情況。在這里介紹第二種用法
wujiahao@VM-12-14-ubuntu:~/gitcode$ git reset HEAD ReadMe
Unstaged changes after reset:
M ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: ReadMeUntracked files:(use "git add <file>..." to include in what will be committed)file5no changes added to commit (use "git add" and/or "git commit -a")
然后再使用和情況1的指令即可
wujiahao@VM-12-14-ubuntu:~/gitcode$ git checkout -- ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ git status
On branch master
Untracked files:(use "git add <file>..." to include in what will be committed)file5nothing added to commit but untracked files present (use "git add" to track)
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
3.已經commit到版本庫,但沒有執行push到遠程倉庫
我們加入 this is the third change,并且add和commit
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
wujiahao@VM-12-14-ubuntu:~/gitcode$ vim ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git
this is the third change
wujiahao@VM-12-14-ubuntu:~/gitcode$ git add ReadMe
wujiahao@VM-12-14-ubuntu:~/gitcode$ git commit -m "Modify ReadMe Third "
[master d6a7559] Modify ReadMe Third1 file changed, 1 insertion(+)
只需要用reset的hard選項即可,HEAD表示當前版本,那么上個版本就是HEAD^
wujiahao@VM-12-14-ubuntu:~/gitcode$ git reset --hard HEAD^
HEAD is now at 1881288 add some files
wujiahao@VM-12-14-ubuntu:~/gitcode$ git status
On branch master
Untracked files:(use "git add <file>..." to include in what will be committed)file5nothing added to commit but untracked files present (use "git add" to track)
wujiahao@VM-12-14-ubuntu:~/gitcode$ cat ReadMe
hello Linux
hello git