git log 和 git reflog 都可以檢視曆史版本commit及其對應的版本号
-
git log
在實際工作中,我們腦子裡怎麼可能記得一個幾千行的檔案每次都改了什麼内容,不然要版本控制系統幹什麼。版本控制系統肯定有某個指令可以告訴我們曆史記錄,在Git中,我們用
git log
指令檢視:
MacBook-Pro-83:incubator-dubbo-ops lmfeng$ git log
commit 3adac8a546440785da7ef1e90ea11b32b8923161 (HEAD -> develop, origin/develop, origin/HEAD)
Author: 孫不服 <[email protected]>
Date: Wed Jan 23 10:33:28 2019 +0800
unit test (#268)
* unit test
* add Apache license & remove *
commit 2d40e623d97d50e76c1ae84474eaeff953ffcfec
Author: kezhenxu94 <[email protected]>
Date: Wed Jan 23 10:32:07 2019 +0800
remove duplicated note in README (#269)
commit 7e1a3471f0c4dd7582a28d0700090d142fef56c5
Author: Yuhao Bi <[email protected]>
Date: Wed Jan 23 07:38:54 2019 +0800
Add missing license announcement (#271)
git log
指令顯示從最近到最遠的送出日志,我們可以看到3次送出,最近的一次是
unit test (#268)
,上一次是
remove duplicated note in README (#269)
,最早的一次是
Add missing license announcement (#271)
。
如果嫌輸出資訊太多,看得眼花缭亂的,可以試試加上
--pretty=oneline
參數:
MacBook-Pro-83:incubator-dubbo-ops lmfeng$ git log --pretty=oneline
3adac8a546440785da7ef1e90ea11b32b8923161 (HEAD -> develop, origin/develop, origin/HEAD) unit test (#268)
2d40e623d97d50e76c1ae84474eaeff953ffcfec remove duplicated note in README (#269)
7e1a3471f0c4dd7582a28d0700090d142fef56c5 Add missing license announcement (#271)
需要友情提示的是,你看到的一大串類似
1094adb...
的是
commit id
(版本号),和SVN不一樣,Git的
commit id
不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進制表示,而且你看到的
commit id
和我的肯定不一樣,以你自己的為準。為什麼
commit id
需要用這麼一大串數字表示呢?因為Git是分布式的版本控制系統,後面我們還要研究多人在同一個版本庫裡工作,如果大家都用1,2,3……作為版本号,那肯定就沖突了。
每送出一個新版本,實際上Git就會把它們自動串成一條時間線。如果使用可視化工具檢視Git曆史,就可以更清楚地看到送出曆史的時間線。
-
git reset
好了,現在我們啟動時光穿梭機,準備回退到上一個版本,也就是
remove duplicated note in README (#269)
的那個版本,怎麼做呢?
首先,Git必須知道目前版本是哪個版本,在Git中,用
HEAD
表示目前版本,也就是最新的送出
1094adb...
(注意我的送出ID和你的肯定不一樣),上一個版本就是
HEAD^
,上上一個版本就是
HEAD^^
,當然往上100個版本寫100個
^
比較容易數不過來,是以寫成
HEAD~100
。
現在,我們要把目前版本
unit test (#268)
回退到上一個版本
remove duplicated note in README (#269)
,就可以使用
git reset
指令:
MacBook-Pro-83:incubator-dubbo-ops lmfeng$ git reset --hard HEAD^
HEAD is now at 2d40e62 remove duplicated note in README (#269)
現在,你回退到了某個版本,關掉了電腦,第二天早上就後悔了,想恢複到新版本怎麼辦?使用git log找不到新版本的
commit id
怎麼辦?
在Git中,總是有後悔藥可以吃的。當你用
$ git reset --hard HEAD^
回退到
remove duplicated note in README (#269)
版本時,再想恢複到
unit test (#268)
,就必須找到
unit test (#268)
的commit id。Git提供了一個指令
git reflog
用來記錄你的每一次指令:
-
git reflog
acBook-Pro-83:incubator-dubbo-ops lmfeng$ git reflog
3adac8a (HEAD -> develop, origin/develop, origin/HEAD) [email protected]{0}: checkout: moving from master to develop
9f98f5a (origin/master, master) [email protected]{1}: checkout: moving from develop to master
3adac8a (HEAD -> develop, origin/develop, origin/HEAD) [email protected]{2}: checkout: moving from master to develop
9f98f5a (origin/master, master) [email protected]{3}: clone: from https://github.com/thinkerFenglm/incubator-dubbo-ops.git
然後就可以使用 git reset 復原
- 場景分析
- 場景一
假如你隻是修改了工作區,還沒有 git add 到暫存區。可以使用下面的指令撤銷工作區中的修改。
# 僅僅是撤銷工作區中的修改
git checkout .
- 場景二
假如你修改了工作區,并把工作區中的修改 git add 到了暫存區。
如果你想撤銷工作區和暫存區中的修改。
git reset --hard head
# 簡寫為
git reset --hard
如果你僅僅隻是想要撤銷暫存區中的修改。
git reset --mixed
# 簡寫為
git reset
- 場景三
假如你修改了工作區,并把工作區中的修改 git add 到了暫存區,然後又 git commit 送出到了版本庫。
如果你想回退到上一個版本,可以使用下面的指令。
git reset --hard head^
檢視目前的版本号,可以使用。
git rev-parse HEAD
需要注意的是,在 Windows 的 CMD 中, ^ 代表換行,即指令沒輸完,在下一行繼續輸指令。它相當于 Linux 中的 \ 。
是以,在 CMD 中回退到上一個版本的寫法,就略有不同。
具體的解決方法有:
git reset --hard "head^"
git reset --hard HEAD^^
git reset --hard HEAD~
git reset --hard HEAD~1
改用 PowerShell 或 Git Bash 終端
還有一個需要注意的問題是,通常我們所說的版本回退是指完整的版本回退。
如果你回退版本時,采用的是 『 git reset --mixed 版本号 』,--mixed 其實本來就是預設選項。那麼,你隻是更改了 head 的指向和回退了暫存區,而并沒有回退工作區。如果想要繼續把工作區也回退,你還需執行下面的指令
git checkout .
這樣,才算完整的版本回退。
完整的版本回退,包含三個要素:
更改 HEAD 指針的指向(即讓 HEAD 指向目标版本)
回退工作區(即工作區中的内容也要回退到目标版本)
回退暫存區(即暫存區中的内容也要回退到目标版本)
為此,推薦使用 git reset --hard 來完成版本回退。