柚子快報(bào)激活碼778899分享:關(guān)于git的相關(guān)知識(shí)內(nèi)容
柚子快報(bào)激活碼778899分享:關(guān)于git的相關(guān)知識(shí)內(nèi)容
目錄
1.下載安裝Git
①在Linux上安裝Git
②在Mac?OS?X上安裝Git
③在Windows上安裝Git
2.創(chuàng)建版本庫
2.1創(chuàng)建空目錄
2.2把目錄變成Git可管理倉庫
2.3把文件添加到版本庫
疑難解答
小結(jié)
3.git?status?/?git?diff
小結(jié)
4.查看歷史
小結(jié)
5.工作區(qū)和暫存區(qū)
工作區(qū)(Working?Directory)
版本庫(Repository)
小結(jié)
6.管理和修改
小結(jié)
7.撤銷修改
小結(jié)
1.下載安裝Git
①在Linux上安裝Git
首先,你可以試著輸入git,看看系統(tǒng)有沒有安裝Git:
$?git
The?program?'git'?is?currently?not?installed.?You?can?install?it?by?typing:
sudo?apt-get?install?git
像上面的命令,有很多Linux會(huì)友好地告訴你Git沒有安裝,還會(huì)告訴你如何安裝Git。
如果你碰巧用Debian或Ubuntu?Linux,通過一條sudo?apt-get?install?git就可以直接完成Git的安裝,非常簡單。
老一點(diǎn)的Debian或Ubuntu?Linux,要把命令改為sudo?apt-get?install?git-core,因?yàn)橐郧坝袀€(gè)軟件也叫GIT(GNU?Interactive?Tools),結(jié)果Git就只能叫g(shù)it-core了。由于Git名氣實(shí)在太大,后來就把GNU?Interactive?Tools改成gnuit,git-core正式改為git。
如果是其他Linux版本,可以直接通過源碼安裝。先從Git官網(wǎng)下載源碼,然后解壓,依次輸入:./config,make,sudo?make?install這幾個(gè)命令安裝就好了。
②在Mac?OS?X上安裝Git
如果你正在使用Mac做開發(fā),有兩種安裝Git的方法。
一是安裝homebrew,然后通過homebrew安裝Git,具體方法請(qǐng)參考homebrew的文檔:Homebrew — The Missing Package Manager for macOS (or Linux)。
第二種方法更簡單,也是推薦的方法,就是直接從AppStore安裝Xcode,Xcode集成了Git,不過默認(rèn)沒有安裝,你需要運(yùn)行Xcode,選擇菜單“Xcode”->“Preferences”,在彈出窗口中找到“Downloads”,選擇“Command?Line?Tools”,點(diǎn)“Install”就可以完成安裝了。
Xcode是Apple官方IDE,功能非常強(qiáng)大,是開發(fā)Mac和iOS?App的必選裝備,而且是免費(fèi)的!
③在Windows上安裝Git
在Windows上使用Git,可以從Git官網(wǎng)直接Git - Downloads,然后按默認(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)心,首先我們相信大家都是善良無知的群眾,其次,真的有冒充的也是有辦法可查的。
注意git?config命令的--global參數(shù),用了這個(gè)參數(shù),表示你這臺(tái)機(jī)器上所有的Git倉庫都會(huì)使用這個(gè)配置,當(dāng)然也可以對(duì)某個(gè)倉庫指定不同的用戶名和Email地址。
2.創(chuàng)建版本庫
版本庫又名倉庫,英文名repository,你可以簡單理解成一個(gè)目錄,這個(gè)目錄里面的所有文件都可以被Git管理起來,每個(gè)文件的修改、刪除,Git都能跟蹤,以便任何時(shí)刻都可以追蹤歷史,或者在將來某個(gè)時(shí)刻可以“還原”。
2.1創(chuàng)建空目錄
所以,創(chuàng)建一個(gè)版本庫非常簡單,首先,選擇一個(gè)合適的地方,創(chuàng)建一個(gè)空目錄:
$?mkdir?learngit
$?cd?learngit
$?pwd
/Users/michael/learngit
①mkdir???learngit創(chuàng)建文件夾learngit
②cd?learngit??cd命令,后面跟上要進(jìn)入的目錄的路徑
③pwd命令用于顯示當(dāng)前目錄。
可以看到D盤有了learngit文件夾
2.2把目錄變成Git可管理倉庫
第二步,通過git?init命令把這個(gè)目錄變成Git可以管理的倉庫:
$?git?init
Initialized?empty?Git?repository?in?/Users/michael/learngit/.git/
瞬間Git就把倉庫建好了,而且告訴你是一個(gè)空的倉庫(empty?Git?repository),細(xì)心的讀者可以發(fā)現(xiàn)當(dāng)前目錄下多了一個(gè).git的目錄,這個(gè)目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動(dòng)修改這個(gè)目錄里面的文件,不然改亂了,就把Git倉庫給破壞了。
如果你沒有看到.git目錄,那是因?yàn)檫@個(gè)目錄默認(rèn)是隱藏的,用ls?-ah命令就可以看見。
2.3把文件添加到版本庫
首先這里再明確一下,所有的版本控制系統(tǒng),其實(shí)只能跟蹤文本文件的改動(dòng),比如TXT文件,網(wǎng)頁,所有的程序代碼等等,Git也不例外。版本控制系統(tǒng)可以告訴你每次的改動(dòng),比如在第5行加了一個(gè)單詞“Linux”,在第8行刪了一個(gè)單詞“Windows”。而圖片、視頻這些二進(jìn)制文件,雖然也能由版本控制系統(tǒng)管理,但沒法跟蹤文件的變化,只能把二進(jìn)制文件每次改動(dòng)串起來,也就是只知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統(tǒng)不知道,也沒法知道。
不幸的是,Microsoft的Word格式是二進(jìn)制格式,因此,版本控制系統(tǒng)是沒法跟蹤Word文件的改動(dòng)的,前面我們舉的例子只是為了演示,如果要真正使用版本控制系統(tǒng),就要以純文本方式編寫文件。
因?yàn)槲谋臼怯芯幋a的,比如中文有常用的GBK編碼,日文有Shift_JIS編碼,如果沒有歷史遺留問題,強(qiáng)烈建議使用標(biāo)準(zhǔn)的UTF-8編碼,所有語言使用同一種編碼,既沒有沖突,又被所有平臺(tái)所支持。
使用Windows的要特別注意:
千萬不要使用Windows自帶的記事本編輯任何文本文件。原因是Microsoft開發(fā)記事本的團(tuán)隊(duì),他們?cè)诿總€(gè)文件開頭添加了0xefbbbf(十六進(jìn)制)的字符來保存UTF-8編碼的文件,你會(huì)遇到問題,比如,網(wǎng)頁第一行可能會(huì)顯示一個(gè)“?”,明明正確的程序一編譯就報(bào)語法錯(cuò)誤等等。建議你下載Visual Studio Code - Code Editing. Redefined代替記事本,不但功能強(qiáng)大,而且免費(fèi)!
編寫一個(gè)readme.txt文件,放到learngit目錄下,內(nèi)容如下:
vim?readme.txt會(huì)進(jìn)入readme.txt文件內(nèi),摁鍵盤上字母I??就可以進(jìn)行輸入,把下面代碼輸入進(jìn)去
Git?is?a?version?control?system.
Git?is?free?software.
輸入完成后,摁ESC鍵,輸入:wq??回車,進(jìn)行保存退出。
把一個(gè)文件放到Git倉庫只需要兩步:
第一步,用命令git?add告訴Git,把文件添加到倉庫:
$?git?add?readme.txt
執(zhí)行上面的命令,沒有任何顯示,說明添加成功。
如果報(bào)錯(cuò):
再輸入?cd?+你的learngit所在路徑:
就會(huì)看到不再報(bào)錯(cuò),文件夾也會(huì)出現(xiàn)readme.txt文件
小提示:clear命令可以清屏,history命令可以看你輸入的所有命令
第二步,用命令git?commit告訴Git,把文件提交到倉庫:
$?git?commit?-m?"wrote?a?readme?file"
[master?(root-commit)?eaadf4e]?wrote?a?readme?file
?1?file?changed,?2?insertions(+)
?create?mode?100644?readme.txt
簡單解釋一下git?commit命令,-m后面輸入的是本次提交的說明,可以輸入任意內(nèi)容,當(dāng)然最好是有意義的,這樣你就能從歷史記錄里方便地找到改動(dòng)記錄。
git?commit命令執(zhí)行成功后會(huì)告訴你,1?file?changed:1個(gè)文件被改動(dòng)(我們新添加的readme.txt文件);2?insertions:插入了兩行內(nèi)容(readme.txt有兩行內(nèi)容)。
為什么Git添加文件需要add,commit一共兩步呢?因?yàn)閏ommit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$?git?add?file1.txt
$?git?add?file2.txt?file3.txt
$?git?commit?-m?"add?3?files."
如果你發(fā)現(xiàn)報(bào)錯(cuò):
是因?yàn)槟銢]有file1.txt文件,此時(shí)輸入(touch創(chuàng)建文件,mkdir創(chuàng)建文件夾):
會(huì)發(fā)現(xiàn)執(zhí)行正常,同時(shí)創(chuàng)建file2.txt和?file.txt
文件夾內(nèi)也相應(yīng)出現(xiàn)文件
疑難解答
Q:輸入git?add?readme.txt,得到錯(cuò)誤:fatal:?not?a?git?repository?(or?any?of?the?parent?directories)。
A:Git命令必須在Git倉庫目錄內(nèi)執(zhí)行(git?init除外),在倉庫目錄外執(zhí)行是沒有意義的。
Q:輸入git?add?readme.txt,得到錯(cuò)誤fatal:?pathspec?'readme.txt'?did?not?match?any?files。
A:添加某個(gè)文件時(shí),該文件必須在當(dāng)前目錄下存在,用ls或者dir命令查看當(dāng)前目錄的文件,看看文件是否存在,或者是否寫錯(cuò)了文件名。
小結(jié)
現(xiàn)在總結(jié)一下今天學(xué)的兩點(diǎn)內(nèi)容:
初始化一個(gè)Git倉庫,使用git?init命令。
添加文件到Git倉庫,分兩步:
使用命令git?add?
3.git?status?/?git?diff
修改readme.txt文件,改成如下內(nèi)容:
Git?is?a?distributed?version?control?system.
Git?is?free?software.
①
②
現(xiàn)在,運(yùn)行g(shù)it?status命令看看結(jié)果:
$?git?status
On?branch?master
Changes?not?staged?for?commit:
??(use?"git?add?
??(use?"git?checkout?--?
modified:???readme.txt
no?changes?added?to?commit?(use?"git?add"?and/or?"git?commit?-a")
git?status命令可以讓我們時(shí)刻掌握倉庫當(dāng)前的狀態(tài),上面的命令輸出告訴我們,readme.txt被修改過了,但還沒有準(zhǔn)備提交的修改。
雖然Git告訴我們r(jià)eadme.txt被修改了,但如果能看看具體修改了什么內(nèi)容,自然是很好的。比如你休假兩周從國外回來,第一天上班時(shí),已經(jīng)記不清上次怎么修改的readme.txt,所以,需要用git?diff這個(gè)命令看看:
$?git?diff?readme.txt?
diff?--git?a/readme.txt?b/readme.txt
index?46d49bf..9247db6?100644
---?a/readme.txt
+++?b/readme.txt
@@?-1,2?+1,2?@@
-Git?is?a?version?control?system.
+Git?is?a?distributed?version?control?system.
?Git?is?free?software.
git?diff顧名思義就是查看difference,顯示的格式正是Unix通用的diff格式,可以從上面的命令輸出看到,我們?cè)诘谝恍刑砑恿艘粋€(gè)distributed單詞。
知道了對(duì)readme.txt作了什么修改后,再把它提交到倉庫就放心多了,提交修改和提交新文件是一樣的兩步,第一步是git?add:
$?git?add?readme.txt
同樣沒有任何輸出。
如果報(bào)錯(cuò):
就進(jìn)行:
在執(zhí)行第二步git?commit之前,我們?cè)龠\(yùn)行g(shù)it?status看看當(dāng)前倉庫的狀態(tài):
$?git?status
On?branch?master
Changes?to?be?committed:
??(use?"git?reset?HEAD?
modified:???readme.txt
git?status告訴我們,將要被提交的修改包括readme.txt,下一步,就可以提交了:
$?git?commit?-m?"add?distributed"
[master?e475afc]?add?distributed
?1?file?changed,?1?insertion(+),?1?deletion(-)
提交后,我們?cè)儆胓it?status命令看看倉庫的當(dāng)前狀態(tài):
$?git?status
On?branch?master
nothing?to?commit,?working?tree?clean
Git告訴我們當(dāng)前沒有需要提交的修改,而且,工作目錄是干凈(working?tree?clean)的。
小結(jié)
要隨時(shí)掌握工作區(qū)的狀態(tài),使用git?status命令。如果git?status告訴你有文件被修改過,用git?diff可以查看修改內(nèi)容。
4.查看歷史
現(xiàn)在,你已經(jīng)學(xué)會(huì)了修改文件,然后把修改提交到Git版本庫,現(xiàn)在,再練習(xí)一次,修改readme.txt文件如下:
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
然后嘗試提交:
$?git?add?readme.txt
$?git?commit?-m?"append?GPL"
[master?1094adb]?append?GPL
?1?file?changed,?1?insertion(+),?1?deletion(-)
像這樣,你不斷對(duì)文件進(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?readme?file
Git?is?a?version?control?system.
Git?is?free?software.
版本2:add?distributed
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?1094adb7b9b3807259d8cb349e7df1d4d6477073?(HEAD?->?master)
Author:?Michael?Liao?
Date:???Fri?May?18?21:06:15?2018?+0800
????append?GPL
commit?e475afc93c209a690c39c13a46716e8fa000c366
Author:?Michael?Liao?
Date:???Fri?May?18?21:03:36?2018?+0800
????add?distributed
commit?eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author:?Michael?Liao?
Date:???Fri?May?18?20:59:18?2018?+0800
????wrote?a?readme?file
git?log命令顯示從最近到最遠(yuǎn)的提交日志,我們可以看到3次提交,最近的一次是append?GPL,上一次是add?distributed,最早的一次是wrote?a?readme?file。
如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline參數(shù):
$?git?log?--pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073?(HEAD?->?master)?append?GPL
e475afc93c209a690c39c13a46716e8fa000c366?add?distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0?wrote?a?readme?file
需要友情提示的是,你看到的一大串類似1094adb...的是commit?id(版本號(hào)),和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……作為版本號(hào),那肯定就沖突了。
每提交一個(gè)新版本,實(shí)際上Git就會(huì)把它們自動(dòng)串成一條時(shí)間線。如果使用可視化工具查看Git歷史,就可以更清楚地看到提交歷史的時(shí)間線:
好了,現(xiàn)在我們啟動(dòng)時(shí)光穿梭機(jī),準(zhǔn)備把readme.txt回退到上一個(gè)版本,也就是add?distributed的那個(gè)版本,怎么做呢?
首先,Git必須知道當(dāng)前版本是哪個(gè)版本,在Git中,用HEAD表示當(dāng)前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一樣),上一個(gè)版本就是HEAD^,上上一個(gè)版本就是HEAD^^,當(dāng)然往上100個(gè)版本寫100個(gè)^比較容易數(shù)不過來,所以寫成HEAD~100。
現(xiàn)在,我們要把當(dāng)前版本append?GPL回退到上一個(gè)版本add?distributed,就可以使用git?reset命令:
$?git?reset?--hard?HEAD^
HEAD?is?now?at?e475afc?add?distributed
看看readme.txt的內(nèi)容是不是版本add?distributed:
$?cat?readme.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?e475afc93c209a690c39c13a46716e8fa000c366?(HEAD?->?master)
Author:?Michael?Liao?
Date:???Fri?May?18?21:03:36?2018?+0800
????add?distributed
commit?eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author:?Michael?Liao?
Date:???Fri?May?18?20:59:18?2018?+0800
????wrote?a?readme?file
最新的那個(gè)版本append?GPL已經(jīng)看不到了!
只要上面的命令行窗口還沒有被關(guān)掉,你就可以順著往上找啊找啊,找到那個(gè)append?GPL的commit?id是1094adb...,于是就可以指定回到未來的某個(gè)版本:
$?git?reset?--hard?1094a
HEAD?is?now?at?83b0afe?append?GPL
版本號(hào)沒必要寫全,前幾位就可以了,Git會(huì)自動(dòng)去找。當(dāng)然也不能只寫前一兩位,因?yàn)镚it可能會(huì)找到多個(gè)版本號(hào),就無法確定是哪一個(gè)了。
再小心翼翼地看看readme.txt的內(nèi)容:
$?cat?readme.txt
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git的版本回退速度非???,因?yàn)镚it在內(nèi)部有個(gè)指向當(dāng)前版本的HEAD指針,當(dāng)你回退版本的時(shí)候,Git僅僅是把HEAD從指向append?GPL:
┌────┐
│HEAD│
└────┘
???│
???└──??○?append?GPL
????????│
????????○?add?distributed
????????│
????????○?wrote?a?readme?file
改為指向add?distributed:
┌────┐
│HEAD│
└────┘
???│
???│????○?append?GPL
???│????│
???└──??○?add?distributed
????????│
????????○?wrote?a?readme?file
然后順便把工作區(qū)的文件更新了。所以你讓HEAD指向哪個(gè)版本號(hào),你就把當(dāng)前版本定位在哪。
現(xiàn)在,你回退到了某個(gè)版本,關(guān)掉了電腦,第二天早上就后悔了,想恢復(fù)到新版本怎么辦?找不到新版本的commit?id怎么辦?
當(dāng)你用$?git?reset?--hard?HEAD^回退到add?distributed版本時(shí),再想恢復(fù)到append?GPL,就必須找到append?GPL的commit?id。Git提供了一個(gè)命令git?reflog用來記錄你的每一次命令:
$?git?reflog
e475afc?HEAD@{1}:?reset:?moving?to?HEAD^
1094adb?(HEAD?->?master)?HEAD@{2}:?commit:?append?GPL
e475afc?HEAD@{3}:?commit:?add?distributed
eaadf4e?HEAD@{4}:?commit?(initial):?wrote?a?readme?file
終于舒了口氣,從輸出可知,append?GPL的commit?id是1094adb,現(xiàn)在,你又可以乘坐時(shí)光機(jī)回到未來了。
小結(jié)
現(xiàn)在總結(jié)一下:
HEAD指向的版本就是當(dāng)前版本,因此,Git允許我們?cè)诎姹镜臍v史之間穿梭,使用命令git?reset?--hard?commit_id。穿梭前,用git?log可以查看提交歷史,以便確定要回退到哪個(gè)版本。要重返未來,用git?reflog查看命令歷史,以便確定要回到未來的哪個(gè)版本。
5.工作區(qū)和暫存區(qū)
Git和其他版本控制系統(tǒng)如SVN的一個(gè)不同之處就是有暫存區(qū)的概念。
工作區(qū)(Working?Directory)
就是你在電腦里能看到的目錄,比如我的learngit文件夾就是一個(gè)工作區(qū):
版本庫(Repository)
工作區(qū)有一個(gè)隱藏目錄.git,這個(gè)不算工作區(qū),而是Git的版本庫。
Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區(qū),還有Git為我們自動(dòng)創(chuàng)建的第一個(gè)分支master,以及指向master的一個(gè)指針叫HEAD。
前面講了我們把文件往Git版本庫里添加的時(shí)候,是分兩步執(zhí)行的:
第一步是用git?add把文件添加進(jìn)去,實(shí)際上就是把文件修改添加到暫存區(qū);
第二步是用git?commit提交更改,實(shí)際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支。
因?yàn)槲覀儎?chuàng)建Git版本庫時(shí),Git自動(dòng)為我們創(chuàng)建了唯一一個(gè)master分支,所以,現(xiàn)在,git?commit就是往master分支上提交更改。
可以理解為,需要提交的文件修改通通放到暫存區(qū),然后,一次性提交暫存區(qū)的所有修改。
俗話說,實(shí)踐出真知?,F(xiàn)在,我們?cè)倬毩?xí)一遍,先對(duì)readme.txt做個(gè)修改,比如加上一行內(nèi)容:
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
然后,在工作區(qū)新增一個(gè)LICENSE文本文件(內(nèi)容隨便寫)。
先用git?status查看一下狀態(tài):
$?git?status
On?branch?master
Changes?not?staged?for?commit:
??(use?"git?add?
??(use?"git?checkout?--?
modified:???readme.txt
Untracked?files:
??(use?"git?add?
LICENSE
no?changes?added?to?commit?(use?"git?add"?and/or?"git?commit?-a")
Git非常清楚地告訴我們,readme.txt被修改了,而LICENSE還從來沒有被添加過,所以它的狀態(tài)是Untracked。
現(xiàn)在,使用兩次命令git?add,把readme.txt和LICENSE都添加后,用git?status再查看一下:
$?git?status
On?branch?master
Changes?to?be?committed:
??(use?"git?reset?HEAD?
new?file:???LICENSE
modified:???readme.txt
現(xiàn)在,暫存區(qū)的狀態(tài)就變成這樣了:
所以,git?add命令實(shí)際上就是把要提交的所有修改放到暫存區(qū)(Stage),然后,執(zhí)行g(shù)it?commit就可以一次性把暫存區(qū)的所有修改提交到分支。
$?git?commit?-m?"understand?how?stage?works"
[master?e43a48b]?understand?how?stage?works
?2?files?changed,?2?insertions(+)
?create?mode?100644?LICENSE
一旦提交后,如果你又沒有對(duì)工作區(qū)做任何修改,那么工作區(qū)就是“干凈”的:
$?git?status
On?branch?master
nothing?to?commit,?working?tree?clean
現(xiàn)在版本庫變成了這樣,暫存區(qū)就沒有任何內(nèi)容了:
小結(jié)
暫存區(qū)是Git非常重要的概念,弄明白了暫存區(qū),就弄明白了Git的很多操作到底干了什么。
6.管理和修改
為什么Git比其他版本控制系統(tǒng)設(shè)計(jì)得優(yōu)秀,因?yàn)镚it跟蹤并管理的是修改,而非文件。
你會(huì)問,什么是修改?比如你新增了一行,這就是一個(gè)修改,刪除了一行,也是一個(gè)修改,更改了某些字符,也是一個(gè)修改,刪了一些又加了一些,也是一個(gè)修改,甚至創(chuàng)建一個(gè)新文件,也算一個(gè)修改。
為什么說Git管理的是修改,而不是文件呢?我們還是做實(shí)驗(yàn)。第一步,對(duì)readme.txt做一個(gè)修改,比如加一行內(nèi)容:
$?cat?readme.txt
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
Git?tracks?changes.
然后,添加:
$?git?add?readme.txt
$?git?status
#?On?branch?master
#?Changes?to?be?committed:
#???(use?"git?reset?HEAD?
#
#???????modified:???readme.txt
#
然后,再修改readme.txt:
$?cat?readme.txt?
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
Git?tracks?changes?of?files.
提交:
$?git?commit?-m?"git?tracks?changes"
[master?519219b]?git?tracks?changes
?1?file?changed,?1?insertion(+)
提交后,再看看狀態(tài):
$?git?status
On?branch?master
Changes?not?staged?for?commit:
??(use?"git?add?
??(use?"git?checkout?--?
modified:???readme.txt
no?changes?added?to?commit?(use?"git?add"?and/or?"git?commit?-a")
咦,怎么第二次的修改沒有被提交?
別激動(dòng),我們回顧一下操作過程:
第一次修改?->?git?add?->?第二次修改?->?git?commit
Git管理的是修改,當(dāng)你用git?add命令后,在工作區(qū)的第一次修改被放入暫存區(qū),準(zhǔn)備提交,但是,在工作區(qū)的第二次修改并沒有放入暫存區(qū),所以,git?commit只負(fù)責(zé)把暫存區(qū)的修改提交了,也就是第一次的修改被提交了,第二次的修改不會(huì)被提交。
提交后,用git?diff?HEAD?--?readme.txt命令可以查看工作區(qū)和版本庫里面最新版本的區(qū)別:
$?git?diff?HEAD?--?readme.txt?
diff?--git?a/readme.txt?b/readme.txt
index?76d770f..a9c5755?100644
---?a/readme.txt
+++?b/readme.txt
@@?-1,4?+1,4?@@
?Git?is?a?distributed?version?control?system.
?Git?is?free?software?distributed?under?the?GPL.
?Git?has?a?mutable?index?called?stage.
-Git?tracks?changes.
+Git?tracks?changes?of?files.
可見,第二次修改確實(shí)沒有被提交。
那怎么提交第二次修改呢?你可以繼續(xù)git?add再git?commit,也可以別著急提交第一次修改,先git?add第二次修改,再git?commit,就相當(dāng)于把兩次修改合并后一塊提交了:
第一次修改?->?git?add?->?第二次修改?->?git?add?->?git?commit
現(xiàn)在,把第二次修改提交了。
①第一次修改:
②第二次修改:
發(fā)現(xiàn)修改并沒有提交,接下來做
小結(jié)
現(xiàn)在,你又理解了Git是如何跟蹤修改的,每次修改,如果不用git?add到暫存區(qū),那就不會(huì)加入到commit中。
7.撤銷修改
在readme.txt中添加了一行:
$?cat?readme.txt
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
Git?tracks?changes?of?files.
My?stupid?boss?still?prefers?SVN.
發(fā)現(xiàn)添加的一行有錯(cuò)誤,現(xiàn)在可以選擇刪掉最后一行,手動(dòng)把文件恢復(fù)到上一個(gè)版本的狀態(tài)。如果用git?status查看一下:
$?git?status
On?branch?master
Changes?not?staged?for?commit:
??(use?"git?add?
??(use?"git?checkout?--?
modified:???readme.txt
no?changes?added?to?commit?(use?"git?add"?and/or?"git?commit?-a")
你可以發(fā)現(xiàn),Git會(huì)告訴你,git?checkout?--?file可以丟棄工作區(qū)的修改:
$?git?checkout?--?readme.txt
命令git?checkout?--?readme.txt意思就是,把readme.txt文件在工作區(qū)的修改全部撤銷,這里有兩種情況:
一種是readme.txt自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫一模一樣的狀態(tài);
一種是readme.txt已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)。
總之,就是讓這個(gè)文件回到最近一次git?commit或git?add時(shí)的狀態(tài)。
現(xiàn)在,看看readme.txt的文件內(nèi)容:
$?cat?readme.txt
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
Git?tracks?changes?of?files.
文件內(nèi)容復(fù)原了。
git?checkout?--?file命令中的--很重要,沒有--,就變成了“切換到另一個(gè)分支”的命令,我們?cè)诤竺娴姆种Ч芾碇袝?huì)再次遇到git?checkout命令。
git?add之后:
$?cat?readme.txt
Git?is?a?distributed?version?control?system.
Git?is?free?software?distributed?under?the?GPL.
Git?has?a?mutable?index?called?stage.
Git?tracks?changes?of?files.
My?stupid?boss?still?prefers?SVN.
$?git?add?readme.txt
慶幸的是,在commit之前,你發(fā)現(xiàn)了這個(gè)問題。用git?status查看一下,修改只是添加到了暫存區(qū),還沒有提交:
$?git?status
On?branch?master
Changes?to?be?committed:
??(use?"git?reset?HEAD?
modified:???readme.txt
Git同樣告訴我們,用命令git?reset?HEAD?
$?git?reset?HEAD?readme.txt
Unstaged?changes?after?reset:
M readme.txt
git?reset命令既可以回退版本,也可以把暫存區(qū)的修改回退到工作區(qū)。當(dāng)我們用HEAD時(shí),表示最新的版本。
再用git?status查看一下,現(xiàn)在暫存區(qū)是干凈的,工作區(qū)有修改:
$?git?status
On?branch?master
Changes?not?staged?for?commit:
??(use?"git?add?
??(use?"git?checkout?--?
modified:???readme.txt
還記得如何丟棄工作區(qū)的修改嗎?
$?git?checkout?--?readme.txt
$?git?status
On?branch?master
nothing?to?commit,?working?tree?clean
現(xiàn)在,假設(shè)你不但改錯(cuò)了東西,還從暫存區(qū)提交到了版本庫,怎么辦呢?可以回退到上一個(gè)版本。不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠(yuǎn)程。
小結(jié)
場(chǎng)景1:當(dāng)你改亂了工作區(qū)某個(gè)文件的內(nèi)容,想直接丟棄工作區(qū)的修改時(shí):
? ? 用命令git?checkout?--?file。
場(chǎng)景2:當(dāng)你不但改亂了工作區(qū)某個(gè)文件的內(nèi)容,還添加到了暫存區(qū)時(shí),想丟棄修改,分兩步,第一步用命令git?reset?HEAD?
場(chǎng)景3:已經(jīng)提交了不合適的修改到版本庫時(shí),想要撤銷本次提交,參考版本回退一節(jié),不過前提是沒有推送到遠(yuǎn)程庫。
柚子快報(bào)激活碼778899分享:關(guān)于git的相關(guān)知識(shí)內(nèi)容
精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。