天天看點

git log 和 git reflog

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 來完成版本回退。