像Git這種版本控制系統的作用就像我們游戲中的存檔,Git也是一樣,每當你覺得文件修改到一定程度的時候,就可以“保存一個快照”,這個快照在Git中被稱為commit
。一旦你把文件改亂了,或者誤刪了文件,還可以從最近的一個commit
恢復,然后繼續工作,而不是把幾個月的工作成果全部丟失。
使用Git log 告訴我們歷史記錄:顯示順序從最近到最遠
λ git log commit c72e38e4abebd7bc0a33332af2a5f96df6598bf0 (HEAD -> master) Author: Gaoking <1903843477@qq.com> Date: Sun Jun 30 22:12:32 2019 +0800 '添加了單詞distributed' commit 06bcd78a4d208dbba023a6e19367340117a468bc Author: Gaoking <1903843477@qq.com> Date: Sun Jun 30 21:53:14 2019 +0800 '添加了三個文件' commit b30fedbae168a3af37f589ea58102bf7a87f93d7 Author: Gaoking <1903843477@qq.com> Date: Sun Jun 30 21:49:56 2019 +0800 創建了一個readme.txt
如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline
參數:
λ git log --pretty=oneline 7acc5230bf659da048f6e532ce944400c73902cc (HEAD -> master) '再次修改readme.txt' c72e38e4abebd7bc0a33332af2a5f96df6598bf0 '添加了單詞distributed' 06bcd78a4d208dbba023a6e19367340117a468bc '添加了三個文件' b30fedbae168a3af37f589ea58102bf7a87f93d7 創建了一個readme.txt
需要友情提示的是,你看到的一大串類似1094adb...
的是commit id
(版本號),和SVN不一樣,Git的commit id
不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進制表示,而且你看到的commit id
和我的肯定不一樣,以你自己的為准。為什么commit id
需要用這么一大串數字表示呢?因為Git是分布式的版本控制系統,后面我們還要研究多人在同一個版本庫里工作,如果大家都用1,2,3……作為版本號,那肯定就沖突了。
回退版本Git reset(reset:重啟)
首先,Git必須知道當前版本是哪個版本,在Git中,用HEAD
表示當前版本,也就是最新的提交1094adb...
(注意我的提交ID和你的肯定不一樣),上一個版本就是HEAD^
,上上一個版本就是HEAD^^
,當然往上100個版本寫100個^
比較容易數不過來,所以寫成HEAD~100
。
#錯誤的一個 λ git reset --hard head^ More? More? y fatal: ambiguous argument 'head y': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' #以為正確的,大意了,看到信息不一樣就沒有細看 λ git reset HEAD^ --hard HEAD is now at 7acc523 '再次修改readme.txt' #真正正確的 λ git reset --hard HEAD^^ HEAD is now at c72e38e '添加了單詞distributed' λ git reset --hard HEAD~1 HEAD is now at 06bcd78 '添加了三個文件'
錯誤的原因:
因為cmd中^是轉義符號,相當於linux的\,當出現在行尾的時候含義是這行還沒寫完,無視行尾的換行符,下行的內容實際執行的時候理解為直接接在上一行尾上。所以你^結尾會提示你More,就是讓你輸入下一行的內容。解決方法有用雙引號括上強行指定為字符串內容"^",或者用兩個^,即^^,前一個轉義后一個,代表一個沒有特殊含義的字符^本身。如果你要用n個^,就要寫2n個^。cmd中是這樣,所以Git cmd也是這樣,Git Bash是Unix風格,應該就沒有這個問題。
查看一下
λ cat readme.txt Git is a version control system. Git is free software.
還可以繼續回退到上一個版本wrote a readme file
,不過且慢,然我們用git log
再看看現在版本庫的狀態:
λ git log --pretty=oneline 06bcd78a4d208dbba023a6e19367340117a468bc (HEAD -> master) '添加了三個文件' b30fedbae168a3af37f589ea58102bf7a87f93d7 創建了一個readme.txt
最新的那個版本append GPL
已經看不到了!好比你從21世紀坐時光穿梭機來到了19世紀,想再回去已經回不去了,腫么辦?
辦法其實還是有的,只要上面的命令行窗口還沒有被關掉,你就可以順着往上找啊找啊,找到那個append GPL
的commit id
是1094adb...
,於是就可以指定回到未來的某個版本:
λ git reset --hard c72e HEAD is now at c72e38e '添加了單詞distributed'
版本號沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能只寫前一兩位,因為Git可能會找到多個版本號,就無法確定是哪一個了。
記錄命令的命令: git reflog
那要是在前面我們找不到了commit id了怎么辦,git有回退到過去可以用head,但是要回到未來,就必須有commit id,我們可以運行git reflog命令來查看不同版本的commit id
λ git reflog c72e38e (HEAD -> master) HEAD@{0}: reset: moving to c72e 06bcd78 HEAD@{1}: reset: moving to HEAD~1 c72e38e (HEAD -> master) HEAD@{2}: reset: moving to HEAD^ 7acc523 HEAD@{3}: reset: moving to HEAD 7acc523 HEAD@{4}: commit: '再次修改readme.txt'#這個是最近的 c72e38e (HEAD -> master) HEAD@{5}: commit: '添加了單詞distributed'#比如這個版本的id 就是 c72e38e,這個是當前的 06bcd78 HEAD@{6}: commit: '添加了三個文件' b30fedb HEAD@{7}: commit (initial): 創建了一個readme.txt
我們回到未來:‘再次修改readme.txt'
λ git reset --hard 7acc523 HEAD is now at 7acc523 '再次修改readme.txt' λ cat readme.txt Git is a distributed version control system. Git is free software distributed under the GPL.
OK!
總結:
-
HEAD
指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git reset --hard commit_id
。 -
穿梭前,用
git log
可以查看提交歷史,以便確定要回退到哪個版本。 -
要重返未來,用
git reflog
查看命令歷史,以便確定要回到未來的哪個版本。