git學(xué)習(xí)筆記

git簡介

是目前世界上先進(jìn)的分布式版本控制系統(tǒng)(沒有之?)。 不但能自動(dòng)幫我記錄每次文件的改動(dòng),還可以讓同事協(xié)作編輯,這樣就不用自己管理一堆類似的文件了,也不需要把文件傳來傳去。Linus花了兩周時(shí)間自己用C寫了一個(gè)分布式版本控制系統(tǒng),這就是Git!一個(gè)月之內(nèi),Linux 系統(tǒng)的源碼已經(jīng)由Git管理了!Git迅速成為流?行的分布式版本控制系統(tǒng),尤其是2008年,GitHub網(wǎng)站上線了,它為開源項(xiàng)目免費(fèi)提供Git存儲,無數(shù)開源項(xiàng)目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

集中式vs分布式

CVS及SVN都是集中式的版本控制系統(tǒng),而Git是分布式版本控制系統(tǒng)。
先說集中式版本控制系統(tǒng),版本庫是集中存放在中央服務(wù)器的,而干活的時(shí)候,用的都是自己的電腦,所以要先從中央服務(wù)器取得新的版本,然后開始干 活,干完活了,再把自? 的活推送給中央服務(wù)器。中央服務(wù)器就好比是一個(gè)圖書館,你要改一本書,必須先從圖書館借出來,然后回到家自己改,改完了,再放回圖書館。

集中式

集中式版本控制系統(tǒng)?大的?毛病就是必須聯(lián)網(wǎng)才能工作,如果在局域網(wǎng)內(nèi)還好,帶寬夠大, 速度夠快,可如果在互聯(lián)網(wǎng)上,遇到網(wǎng)速慢的話,可能提交一個(gè)10M的?文件就需要5分鐘, 這還不得把?人給憋死啊。

那分布式版本控制系統(tǒng)與集中式版本控制系統(tǒng)有何不同呢?首先,分布式版本控制系統(tǒng)根本 沒有“中央服務(wù)器”,每個(gè)人的電腦上都是一個(gè)完整的版本庫,這 樣,你工作的時(shí)候,就 不需要聯(lián)網(wǎng)了,因?yàn)榘姹編炀驮谀阕约旱碾娔X上。既然每個(gè)人電腦上都有?一個(gè)完整的版本 庫,那多個(gè)人如何協(xié)作呢?比方說你在自己電腦上改 了文件A,你的同事也在他的電腦上改 了文件A,這時(shí),你們倆之間只需把各?自的修改推送給對方,就可以互相看到對方的修改 了。
和集中式版本控制系統(tǒng)相比,分布式版本控制系統(tǒng)的安全性要?高很多,因?yàn)槊總€(gè)?人電腦里都有完整的版本庫,某一個(gè)人的電腦壞掉了不要緊,隨便從其他人那里復(fù)制一個(gè)就可以了。而 集中式版本控制系統(tǒng)的中央服務(wù)器要是出了問題,所有人都沒法干活了。
在實(shí)際使用分布式版本控制系統(tǒng)的時(shí)候,其實(shí)很少在兩人之間的電腦上推送版本庫的修改, 因?yàn)榭赡苣銈儌z不在?一個(gè)局域網(wǎng)內(nèi),兩臺電腦互相訪問不了,也 能今天你的同事病了, 他的電腦壓根沒有開機(jī)。因此,分布式版本控制系統(tǒng)通常也有一臺充當(dāng)“中央服務(wù)器”的電 腦,但這個(gè)服務(wù)器的作用僅僅是用來方便“交換” 大家的修改,沒有它大家也?樣干活, 只是交換修改不方便而已。


分布式

當(dāng)然,Git的優(yōu)勢不單是不必聯(lián)網(wǎng)這么簡單,后面我們還會(huì)看到Git極其強(qiáng)大的分支管理,把 SVN等遠(yuǎn)遠(yuǎn)拋在了后?面。

Ubuntu 版

安裝

首先,你可以試著輸入git,看看系統(tǒng)有沒有安裝Git:

 $ git 
The program 'git' is currently not installed. You can install it by typing:```
 $ sudo apt-get install git 

可以如下代碼安裝git

 $ sudo apt-get install git

驗(yàn)證是否安裝成功

 $ git

若執(zhí)行g(shù)it命令如圖所示,則證明已安裝成功


驗(yàn)證git是否安裝成功

安裝完成后,還需要后一步設(shè)置,在命令行輸入:

$ git config --global user.name "Your Name" 
$ git config --global user.email "email@example.com" 

因?yàn)镚it是分布式版本控制系統(tǒng),所以,每個(gè)機(jī)器都必須自報(bào)家門:你的名字和Email地址。你也許會(huì)擔(dān)心,如果有人故意冒充別人怎么辦?這個(gè)不必?fù)?dān)心,首先我們相信大家都是善良無知的群眾,其次,真的有冒充的也是有辦法可查的。

創(chuàng)建倉庫

創(chuàng)建一個(gè)版本庫非常簡單,首先,選擇一個(gè)合適的地?方,創(chuàng)建一個(gè)空目錄:

$ mkdir git 
$ cd git 
$ pwd 
/home/gaoyang/git

第二步,通過git init命令把這個(gè)目錄變成Git可以管理的倉庫:

$ git commit -m "wrote a readme file"
 [master (root-commit) cb926e7] wrote a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt 

簡單解釋一下git commit命令,-m后?面輸入的是本次提交的說明,可以輸入任意內(nèi)容,當(dāng)然好是有意義的,這樣你就能從歷史記錄里方便地找到改動(dòng)記錄。
嫌麻煩不想輸入-m "xxx"行不行?確實(shí)有辦法可以這么干,但是強(qiáng)烈不建議你這么干,因?yàn)檩斎胝f明對自己對別人閱讀都很重要。實(shí)在不想輸入說明的童鞋請自行Google,我不告訴 你這個(gè)參數(shù)。
git commit命令執(zhí)行成功后會(huì)告訴你,1個(gè)文件被改動(dòng)(我們新添加的readme.txt文件),插入了兩行內(nèi)容(readme.txt有兩行內(nèi)容)。

為什么Git添加?文件需要add,commit?一共兩步呢?因?yàn)閏ommit可以?一次提交很多?文件, 所以你可以多次add不同的?文件,比如:

$ git add file1.txt 
$ git add file2.txt 
$ git add file3.txt
$ git commit -m "add 3 files."

小結(jié)
初始化一個(gè)Git倉庫,使用git init命令。
添加?文件到Git倉庫,分兩步:
? 第一步,使用命令git add ,注意,可反復(fù)多次使用,添加多個(gè)文件;
? 第二步,使用命令git commit,完成。

時(shí)光機(jī)穿梭

運(yùn)?行git status命令看看結(jié)果:

$ 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:   redame.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    "../Git\346\225\231\347\250\213.pdf"

no changes added to commit (use "git add" and/or "git commit -a")
倉庫當(dāng)前的狀態(tài)

git status命令可以讓我們時(shí)刻掌握倉庫當(dāng)前的狀態(tài),上面的命令告訴我們,readme.txt被 修改過了,但還沒有準(zhǔn)備提交的修改。
雖然Git告訴我們r(jià)edame.txt被修改了,但如果能看看具體修改了什么內(nèi)容,自然是很好的。比如你休假兩周從國外回來,第一天上班時(shí),已經(jīng)記不清上次怎么修改的 redame.txt,所以,需要用git diff這個(gè)命令看看:

$ git diff redame.txt 
diff --git a/learn/redame.txt b/learn/redame.txt
index 46d49bf..9247db6 100644
--- a/learn/redame.txt
+++ b/learn/redame.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
 Git is free software.
image.png

git diff顧名思義就是查看difference,?示的格式正是Unix通用的diff格式,可以從上面的命令輸出看到,我們在第一行添加了一個(gè)“distributed”單詞。
知道了對redame.txt作了什么修改后,再把它提交到倉庫就放?心多了,提交修改和提交新文件是一樣的兩步,第一步是git add:

git add redame.txt 

同樣沒有任何輸出。在執(zhí)行第二步git commit之前,我們再運(yùn)行g(shù)it status看看當(dāng)前倉庫的狀 態(tài):

git status 
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    learnNot.txt

nothing added to commit but untracked files present (use "git add" to track)

應(yīng)該是之前已經(jīng)提交過redame.txt了,并且我重新向git中添加了learnNot.txt文檔。所以查看當(dāng)前狀態(tài)是這樣的情況。我們繼續(xù)提交learnNot.txt文檔,所用到的命令是一樣的。提交learnNot.txt文檔:

git commit -m 'hello'
On branch master
Untracked files:
    learnNot.txt

nothing added to commit but untracked files present

查看當(dāng)前狀態(tài):

git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    learnNot.txt

nothing added to commit but untracked files present (use "git add" to track)
缺少步驟的錯(cuò)誤提交方式

恩,雖然英語不太好,但還是勉強(qiáng)讀懂了。貌似是之前add的是redame.txt,然而commit的是learnNot.txt。故導(dǎo)致提交失敗,嘗試重新add,再commit:

git add learnNot.txt 
gaoyang@ubuntu:~/git/learn$ git commit -m 'hello'
[master 5cbe811] hello
 1 file changed, 2 insertions(+)
 create mode 100644 learn/learnNot.txt
gaoyang@ubuntu:~/git/learn$ git status 
On branch master
nothing to commit, working directory clean

重新嘗試

說明此前假設(shè)成立,確為add文檔為已經(jīng)提交過且未發(fā)生變化的文檔,而提交的時(shí)候倉庫中存在已經(jīng)發(fā)生變化而未被添加的文檔。

小結(jié)
要隨時(shí)掌握工作區(qū)的狀態(tài),使用git status命令。
如果git status告訴你有文件被修改過,用git diff可以查看修改內(nèi)容。

版本回退

現(xiàn)在,你已經(jīng)知道了如何修改文件,然后把修改提交到Git版本庫,現(xiàn)在,再練習(xí)一次,修改 redame.txt文件如下:
Git is a distributed version control system.
Git is free software distributed under the GPL.

然后嘗試提交:

 git add redame.txt 
gaoyang@ubuntu:~/git/learn$ git commit -m 'append GPL'
[master a51f10d] append GPL
 1 file changed, 2 insertions(+), 2 deletions(-)

像這樣,你不斷對文件進(jìn)行修改,然后不斷提交修改到版本庫里,就好比玩RPG游戲時(shí),每 通過一關(guān)就會(huì)自動(dòng)把游戲狀態(tài)存盤,如果某一關(guān)沒過去,你還可以選擇讀取前一關(guān)的狀 態(tài)。有些時(shí)候,在打Boss之前,你會(huì)手動(dòng)存盤,以便萬一打Boss失敗了,可以從近的地方重新開 始。Git也是?一樣,每當(dāng)你覺得文件修改到一定程度的時(shí)候,就可以“保存一個(gè)快 照”,這個(gè)快照在Git中被稱為commit。一旦你把文件改亂了,或者誤刪了文件,還可以從近的一個(gè)commit恢復(fù),然后繼續(xù)工作,而不是把幾個(gè)月的工作成果全部丟失。 現(xiàn)在,我們回顧一下redame.txt文件一共有幾個(gè)版本被提交到Git倉庫里了:

版本1:
wrote a readme file
Git is a version control system. Git is free software.
版本2:
first commit
Git is a distributed version control system.
Git is free software.
版本3:
append GPL
Git is a distributed version control system.
Git is free software distributed under the GPL.

當(dāng)然了,在實(shí)際工作中,我們腦子里怎么可能記得?一個(gè)幾千行的文件每次都改了什么內(nèi)容, 不然要版本控制系統(tǒng)干什么。版本控制系統(tǒng)肯定有某個(gè)命令可以告訴我們歷史記錄,在Git 中,我們用git log命令查看:

git log
commit a51f10d41c94ae59d7a9a4ec436803c2a63a5627
Author: G.Hope <1638327522@qq.com>
Date:   Sat Jul 21 00:38:39 2018 -0700

    append GPL

commit 5cbe811db86d59ccb1234f287dff57b91dd0c6d3
Author: G.Hope <1638327522@qq.com>
Date:   Sat Jul 21 00:30:18 2018 -0700

    hello

commit 326774bc7579e8a3eb31465b215b23b1ffc3730f
Author: G.Hope <1638327522@qq.com>
Date:   Tue Jul 17 17:39:18 2018 -0700

    first commit

commit c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c
Author: G.Hope <1638327522@qq.com>
Date:   Mon Jul 16 17:50:17 2018 -0700

    wrote a redame file

其中按照時(shí)間由近到遠(yuǎn)的順序從上到下依次排列,其中第二個(gè)版本,也就是我寫文檔打算提交的那個(gè)文檔是前天問老師git diff命令提示出來的信息怎么解讀的時(shí)候老師就幫我提交了那個(gè)文檔。順帶這又想起了我的Ubuntu中并沒有輸入法。。。等會(huì)也把它解決了吧!見另一篇筆記。

當(dāng)然,如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上 --pretty=oneline參數(shù):

git log --pretty=oneline
a51f10d41c94ae59d7a9a4ec436803c2a63a5627 append GPL
5cbe811db86d59ccb1234f287dff57b91dd0c6d3 hello
326774bc7579e8a3eb31465b215b23b1ffc3730f first commit
c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c wrote a redame file

需要友情提示的是,你看到的一大串類似“ 3628164...882e1e0”的是commit id(版本號),和SVN不?一樣,Git的commit id不是1,2,3……遞增的數(shù)字,而是一個(gè)SHA1計(jì)算出來的一個(gè)非常?大的數(shù)字,用十六進(jìn)制表示,而且你看到的commit id和我的肯定不一樣, 以你自己的為準(zhǔn)。為什么commit id需要?用這么一大串?dāng)?shù)字表示呢?因?yàn)镚it是分布式的版本控制系統(tǒng),后?面我們還要研究多?人在同一個(gè)版本庫?里?工作,如果?大家都用1,2,3……作 為版本 號,那肯定就沖突了。

每提交一個(gè)新版本,實(shí)際上Git就會(huì)把它們自動(dòng)串成一條時(shí)間線。如果使用可視化工具查看 Git歷史,就可以更清楚地看到提交歷史的時(shí)間線:


gti 歷史時(shí)間線

好了,現(xiàn)在我們啟動(dòng)時(shí)光穿梭機(jī),準(zhǔn)備把redame.txt回退到上一個(gè)版本,也就是“first commit”的那個(gè)版本,怎么做呢?
首先,Git必須知道當(dāng)前版本是哪個(gè)版本,在Git中,用HEAD表?示當(dāng)前版本,也就是新的提交“ 3628164...882e1e0”(注意我的提交ID和你的肯定不一樣),上一個(gè)版本就是 HEAD,上上一個(gè)版本就是HEAD^,當(dāng)然往上100 個(gè)版本寫100個(gè)^比較容易數(shù)不過來, 所以寫成HEAD~100。
現(xiàn)在,我們要把當(dāng)前版本“append GPL”回退到上?一個(gè)版本“fiest commit”,就可 以使用git reset命令:

git reset --hard HEAD ^
fatal: Cannot do hard reset with paths.
gaoyang@ubuntu:~/git/learn$ git reset --hard HEAD^
HEAD is now at 5cbe811 hello
gaoyang@ubuntu:~/git/learn$ git reset --hard HEAD^
HEAD is now at 326774b first commit

回退到first commit

需要說明的是HEAD^之間不能有空格,類似于HEAD ^就會(huì)報(bào)找不到路徑的錯(cuò)誤。而且版本回退回退到的是hello版本,他們并不是同一個(gè)文件,卻也返回了。我覺得這應(yīng)該就是分支所發(fā)揮的作用吧!后面會(huì)學(xué)到的,總之現(xiàn)在已經(jīng)回退到了‘first commit'版本,--hard參數(shù)有啥意義?這個(gè)后面再講,現(xiàn)在你先放心使用。 看看redame.txt的內(nèi)容是不是版本“first commit”:

cat redame.txt 
Git is a distributed version control system.
Git is free software.

果然。還可以繼續(xù)回退到上一個(gè)版本“wrote a readme file”,不過且慢,然我們用git log再看看現(xiàn)在版本庫的狀態(tài):

git log
commit 326774bc7579e8a3eb31465b215b23b1ffc3730f
Author: G.Hope <1638327522@qq.com>
Date:   Tue Jul 17 17:39:18 2018 -0700

    first commit

commit c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c
Author: G.Hope <1638327522@qq.com>
Date:   Mon Jul 16 17:50:17 2018 -0700

    wrote a redame file

在Git中,總是有后悔藥可以吃的。當(dāng)你用$ git reset --hard HEAD^回退到“first commit”版本時(shí),再想恢復(fù)到“append GPL”,就必須找到“append GPL”的 commit id。Git提供了一個(gè)命令git reflog用來記錄你的每一次命令:

git reflog 
326774b HEAD@{0}: reset: moving to HEAD^
5cbe811 HEAD@{1}: reset: moving to HEAD^
a51f10d HEAD@{2}: commit: append GPL
5cbe811 HEAD@{3}: commit: hello
326774b HEAD@{4}: commit: first commit
c3e0fbf HEAD@{5}: commit (initial): wrote a redame file

指定回到未來的某個(gè) 版本:

git reset --hard a51f10d
HEAD is now at a51f10d append GPL

現(xiàn)在總結(jié)一下:
*HEAD指向的版本就是當(dāng)前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命 令git reset --hard commit_id。
*穿梭前,用git log可以查看提交歷史,以便確定要回退到哪個(gè)版本。
*要重返未來,用git reflog查看命令歷史,以便確定要回到未來的哪個(gè)版本。

Windows 版

安裝

Windows下要使?用很多Linux/Unix的工具時(shí),需要Cygwin這樣的模擬環(huán)境,Git也一樣。 Cygwin的安裝和配置都比較復(fù)雜, 就不建議你折騰了。
不過,有高人已經(jīng)把模擬環(huán)境和 Git都打包好了,名叫msysgit,只需要下載一個(gè)單獨(dú)的exe安裝程序,其他什么也不用裝,絕對好用。 msysgit是Windows版的Git,從http://msysgit.github.io/下載,然后按默認(rèn)選項(xiàng)安裝即可。
安裝完成后,在開始菜單?里找到“Git”->“Git Bash”,蹦出?一個(gè)類似命令?行窗?口的東西,就說明Git安裝成功!

安裝成功界面

安裝完成后,還需要后一步設(shè)置,在命令行輸入:

$ git config --global user.name "Your Name" 
$ git config --global user.email "email@example.com" 

因?yàn)镚it是分布式版本控制系統(tǒng),所以,每個(gè)機(jī)器都必須自報(bào)家門:你的名字和Email地址。你也許會(huì)擔(dān)心,如果有人故意冒充別人怎么辦?這個(gè)不必?fù)?dān)心,首先我們相信大家都是善良無知的群眾,其次,真的有冒充的也是有辦法可查的。

創(chuàng)建倉庫

找到合適的位置(個(gè)人認(rèn)為這是超級麻煩的一步,因?yàn)槟J(rèn)進(jìn)去我的目錄在/c/Users/Machenike下,想去到F盤創(chuàng)建git庫,就先使用cd ..命令回退到根目錄下,在進(jìn)入F盤創(chuàng)建git)

pwd  查看當(dāng)前所在路徑
ls     查看當(dāng)前目錄下文件

cd .. 回退到上一級目錄
cd ./XXX 進(jìn)入當(dāng)前目錄下文件

 mkdir  創(chuàng)建文件夾

因?yàn)槲乙呀?jīng)建立過git,就不再演示如何創(chuàng)建文件夾的操作了,同Linux操作差不多的。

找到所想路徑并建立文件夾

如上,我們已經(jīng)為庫的建立找到了位置。創(chuàng)建一個(gè)空目錄,通過git init命令把這個(gè)目錄變成Git可以管理的倉庫:

mkdir learn
cd learn/
pwd
/f/git/learn
git init
Initialized empty Git repository in F:/git/learn/.git/
恩,感覺圖片比代碼看起更舒服,可惜的是圖片無法復(fù)制其中的代碼,所以代碼還是要有的

在learn中編寫一個(gè)用來測試的文檔,練習(xí)git的基本使用。我創(chuàng)建的是text.txt,文本內(nèi)容是一首有些小錯(cuò)誤的詩:
前無古人,后無來者。
念天地之悠悠,獨(dú)愴然而涕下。
然后使用git add text.txt將測試文本添加入git中,執(zhí)行上面的命令,沒有任何顯示,這就對了,Unix的哲學(xué)是“沒有消息就是好消息”,說明 添加成功。 第二步,用命令git commit告訴Git,把文件提交到倉庫:

git add text.txt
git commit -m "登幽州臺歌"
 1 file changed, 2 insertions(+)
 create mode 100644 text.txt
On branch master
nothing to commit, working tree clean
向倉庫中提交測試文件

時(shí)光穿梭

修改測試文件,將古詩修改正確。修改內(nèi)容如下:
前不見古人,后不見來者。
念天地之悠悠,獨(dú)愴然而涕下。

運(yùn)?行git status命令看看結(jié)果:

 git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <
倉庫當(dāng)前狀態(tài)

git status命令可以讓我們時(shí)刻掌握倉庫當(dāng)前的狀態(tài),上面的命令告訴我們,text.txt被 修改過了,但還沒有準(zhǔn)備提交的修改。
雖然Git告訴我們r(jià)eadme.txt被修改了,但如果能看看具體修改了什么內(nèi)容,自然是很好 的。比如你休假兩周從國外回來,第一天上班時(shí),已經(jīng)記不清上次怎么修改的 readme.txt,所以,需要?用git diff這個(gè)命令看看:

git diff text.txt
diff --git a/text.txt b/text.txt
index 1703de1..8749e44 100644
--- a/text.txt
+++ b/text.txt
@@ -1,2 +1,2 @@
-?<CE>?<C5><C8>?<AC><BA><F3><CE><DE><C0><B4><D5>?<A3>
+?<B2><BB><BC><FB><B9><C5><C8>?<AC><BA>??<FB><C0><B4><D5>?<A3>
<C4><EE><CC><EC><B5><D8>?<D3><C6><D3>?<AC><B6><C0><E2><EB>?<B6><F8><CC><E9><CF>?         <A3>
\ No newline at end of file

查看不同顯示圖

根據(jù)Ubuntu和Windows兩次對于diff命令的使用,我覺得紅色部分應(yīng)該是之前的版本,綠色是修改之后的版本。windows中因?yàn)橹形脑蛩燥@示結(jié)果就看起來很奇怪,不過這不重要了。只需要知道紅色代表之前版本,綠色代表當(dāng)前版本就好了。
知道了對text.txt作了什么修改后,再把它提交到倉庫就放心多了,提交修改和提交新 文件是一樣的兩步,第一步是git add

git add text.txt 

同樣沒有任何輸出。在執(zhí)?行第二步git commit之前,我們再運(yùn)行git status看看當(dāng)前倉庫的狀 態(tài):

git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   text.txt
git add 添加測試

git status告訴我們,將要被提交的修改包括text.txt,下一步,就可以放心地提交了:

git commit -m "write right"
[master 559f1b0] write right
 1 file changed, 1 insertion(+), 1 deletion(-)

提交后,我們再?用git status命令看看倉庫的當(dāng)前狀態(tài):

git status
On branch master
nothing to commit, working tree clean

git commit 提交測試

Git告訴我們當(dāng)前沒有需要提交的修改,而且,工作目錄是干凈(working directory clean)的。
小結(jié)

要隨時(shí)掌握工作區(qū)的狀態(tài),使用git status命令。
如果git status告訴你有文件被修改過,用git diff可以查看修改內(nèi)容。

版本回退

現(xiàn)在,已經(jīng)學(xué)會(huì)了修改文件,然后把修改提交到Git版本庫,現(xiàn)在,再練習(xí)一次,修改 text.txt文件如下:
登幽州臺歌
前不見古人,后不見來者。
念天地之悠悠,獨(dú)愴然而涕下。
然后嘗試提交:

git add text.txt
git commit -m "write complete"
[master e2f20fe] write complete
 1 file changed, 1 insertion(+)
添加提交完整版

像這樣,你不斷對文件進(jìn)行修改,然后不斷提交修改到版本庫里,就好比玩RPG游戲時(shí),每通過一關(guān)就會(huì)?自動(dòng)把游戲狀態(tài)存盤,如果某一關(guān)沒過去,你還可以選擇讀取前一關(guān)的狀 態(tài)。有些時(shí)候,在打Boss之前,你會(huì)手動(dòng)存盤,以便萬一打Boss失敗了,可以從近的地?方 重新開 始。Git也是一樣,每當(dāng)你覺得文件修改到一定程度的時(shí)候,就可以“保存一個(gè)快 照”,這個(gè)快照在Git中被稱為commit。一旦你把文件改亂了,或者誤 刪了文件,還可以 從近的一個(gè)commit恢復(fù),然后繼續(xù)工作,而不是把幾個(gè)月的工作成果全部丟失。
現(xiàn)在,我們回顧一下readme.txt文件一共有幾個(gè)版本被提交到Git倉庫里了:
版本1:
wrote a text file Git is a version control system.
Git is free software.
版本2:
write right Git is a text version control system.
Git is free software.
版本3:
write complete Git is a text version control system.
Git is free software .

當(dāng)然了,在實(shí)際工作中,我們腦子里怎么可能記得一個(gè)幾千行的文件每次都改了什么內(nèi)容, 不然要版本控制系統(tǒng)干什么。版本控制系統(tǒng)肯定有某個(gè)命令可以告訴我們歷史記錄,在Git 中,我們用git log命令查看:


git log
commit e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date:   Thu Jul 19 09:25:53 2018 +0800

    write complete

commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33
Author: G.Hope <1638327522@qq.com>
Date:   Thu Jul 19 09:06:28 2018 +0800

    write right

commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date:   Wed Jul 18 20:49:08 2018 +0800

    登幽州臺歌

git log命令顯示從近到遠(yuǎn)的提交日志,我們可以看到3次提交,近的一次是“write complete”,上一次是“write right”,早的一次是“登幽州臺歌”。 如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上 --pretty=oneline參數(shù):

git log --pretty=oneline
e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master) write complete
559f1b01e06218dd9a10cdae96c84e917bd4bb33 write right
7b70286e53d99055b1f31e20d6fd814d793f89ee 登幽州臺歌

日志查詢

需要友情提示的是,你看到的一大串類似“e2f20fe939de1e410806da1085d58ae64a47fd0f ”的是commit id(版本號),和SVN不一樣,Git的commit id不是1,2,3……遞增的數(shù)字,而是一個(gè)SHA1計(jì)算 出來的一個(gè)非常大的數(shù)字,用十六進(jìn)制表示,而且你看到的commit id和我的肯定不一樣, 以你自己的為準(zhǔn)。為什么commit id需要用這么一大串?dāng)?shù)字表示呢?因?yàn)镚it是分布式的版本控制系統(tǒng),后面我們還要研究多人在同一個(gè)版本庫里工作,如果大家都用1,2,3……作為版本號,那肯定就沖突了。每提交一個(gè)新版本,實(shí)際上Git就會(huì)把它們?自動(dòng)串成一條時(shí)間線。如果使用可視化工具查看Git歷史,就可以更清楚地看到提交歷史的時(shí)間線:


提交歷史時(shí)間線

好了,現(xiàn)在我們啟動(dòng)時(shí)光穿梭機(jī),準(zhǔn)備把text.txt回退到上一個(gè)版本,也就是“write right”的那個(gè)版本,怎么做呢?

首先,Git必須知道當(dāng)前版本是哪個(gè)版本,在Git中,?用HEAD表?示當(dāng)前版本,也就是新的提交“e2f20fe939de1e410806da1085d58ae64a47fd0f ”(注意我的提交ID和你的肯定不一樣),上一個(gè)版本就是 HEAD,上上一個(gè)版本就是HEAD^,當(dāng)然往上100 個(gè)版本寫100個(gè)^比較容易數(shù)不過來, 所以寫成HEAD~100。 現(xiàn)在,我們要把當(dāng)前版本“write complete”回退到上一個(gè)版本“write right”,就可以使用git reset命令:

git reset --hard HEAD^
HEAD is now at 559f1b0 write right

--hard參數(shù)有啥意義?這個(gè)后?面再講,現(xiàn)在你先放?心使?用。 看看text.txt的內(nèi)容是不是版本“write right”:

 cat text.txt
???????????????????
???????????????????????

...,亂碼,我猜測十有八九是中文的原因。所以以后的項(xiàng)目中要切記,如非必要,避免任何中文出現(xiàn)。不過問題不大,用git log再看看現(xiàn)在版本庫的狀態(tài):

git log
commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33 (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date:   Thu Jul 19 09:06:28 2018 +0800

    write right

commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date:   Wed Jul 18 20:49:08 2018 +0800

    登幽州臺歌


版本回退

新的那個(gè)版本“write complexe”已經(jīng)看不到了!好比你從21世紀(jì)坐時(shí)光穿梭機(jī)來到了19 世紀(jì),想再回去已經(jīng)回不去了,腫么辦?
辦法其實(shí)還是有的,只要上面的命令行窗口還沒有被關(guān)掉,你就可以順著往上找啊找啊,找 到那個(gè)“write complexe”的commit id是“e2f20fe939de1e410806da1085d58ae64a47fd0f”,于是就可以指定回到未來的某個(gè)版本:

git reset --hard e2f20fe93
HEAD is now at e2f20fe write complete

查看版本,恩,又是日常亂碼,不過可以通過log(日志)查看是否成功

cat text.txt
         ?????????
???????????????????
???????????????????????

當(dāng)前日志:

git log
commit e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date:   Thu Jul 19 09:25:53 2018 +0800

    write complete

commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33
Author: G.Hope <1638327522@qq.com>
Date:   Thu Jul 19 09:06:28 2018 +0800

    write right

commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date:   Wed Jul 18 20:49:08 2018 +0800

    登幽州臺歌

版本前進(jìn)

Git的版本回退速度非???,因?yàn)镚it在內(nèi)部有個(gè)指向當(dāng)前版本的HEAD指針,當(dāng)你回退版本的時(shí)候,Git僅僅是把HEAD從指向“write complete ”,改為指向“write right”。
然后順便把工作區(qū)的文件更新了。所以你讓HEAD指向哪個(gè)版本號,你就把當(dāng)前版本定位在哪。
現(xiàn)在,你回退到了某個(gè)版本,關(guān)掉了電腦,第二天早上就后悔了,想恢復(fù)到新版本怎么辦? 找不到新版本的commit id怎么辦? 在Git中,總是有后悔藥可以吃的。當(dāng)你用$ git reset --hard HEAD^回退到“write right”版本時(shí),再想恢復(fù)到“write complete”,就必須找到“write complete”的 commit id。
Git提供了一個(gè)命令git reflog用來記錄你的每一次命令:

git reflog
e2f20fe (HEAD -> master) HEAD@{0}: reset: moving to e2f20fe93
559f1b0 HEAD@{1}: reset: moving to HEAD^
e2f20fe (HEAD -> master) HEAD@{2}: commit: write complete
559f1b0 HEAD@{3}: commit: write right
7b70286 HEAD@{4}: commit (initial): 登幽州臺歌

查看所用命令

小結(jié)

現(xiàn)在總結(jié)一下:
? HEAD指向的版本就是當(dāng)前版本,因此,Git允許我們在版本的歷史之間穿梭,使?用命 令git reset --hard commit_id。

? 穿梭前,?用git log可以查看提交歷史,以便確定要回退到哪個(gè)版本。

? 要重返未來,?用git reflog查看命令歷史,以便確定要回到未來的哪個(gè)版本。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Git常用語法 [TOC] Git簡介 描述 ? Git(讀音為/g?t/。)是一個(gè)開源的分布式版本控制系統(tǒng),...
    君惜丶閱讀 3,937評論 0 13
  • Git教程 一、Git簡介 1.1. Git的誕生1.2.集中式的vs分布式 二、安裝Git 三、創(chuàng)建版本庫 四、...
    曹淵說創(chuàng)業(yè)閱讀 1,025評論 0 2
  • ----------------- Git 學(xué)習(xí) ------------------ Git 簡介 Git...
    Junting閱讀 2,357評論 0 3
  • 2月15查到了成績,慘白的分?jǐn)?shù)將我這兩個(gè)月來滿滿的幻想無情地?fù)羲?。分?jǐn)?shù)出現(xiàn)在屏幕上的那一瞬間,感覺空氣都凝固了,充...
    lvlvlvlvlv閱讀 223評論 0 0
  • 每日作業(yè),請各位書友指正!不怕挨磚!
    o_1cca閱讀 709評論 6 6

友情鏈接更多精彩內(nèi)容