更新: 最近新做了一個(gè) slide
聲明1:本文關(guān)于git原理介紹的圖片源自git官網(wǎng)(https://git-scm.com)
聲明2:本文是作者原創(chuàng)文章,如需轉(zhuǎn)載請(qǐng)著名出處。
Git是一款開源的分布式版本管理工具,最初由Linux的締造者林納斯開發(fā),用于Linux的維護(hù)。和svn這類的版本管理工具相比,git更加輕量級(jí),更加高效。
先給出幾個(gè)鏈接:
命令介紹
本文主要針對(duì)CS專業(yè)人士,所以的操作方式均在命令行上進(jìn)行。可視化的窗口操作,不在討論的范圍內(nèi)。如何安裝,請(qǐng)參考上面給出的鏈接,如果你使用的是Mac,那么基本上會(huì)已經(jīng)安裝好了git。請(qǐng)打開命令行(終端,terminal),鍵入:
git --version
系統(tǒng)如果輸入了當(dāng)前的git版本號(hào),進(jìn)行已經(jīng)安裝好,如果提示沒(méi)有此命令,則考慮要下載并安裝git。
本文使用的環(huán)境如下:
Mac pro (macOs Sierra version10.12)
terminal(Zsh)
創(chuàng)建本地倉(cāng)庫(kù)
如果你希望將當(dāng)前目錄使用git進(jìn)行管理,只需在命令行下切換到當(dāng)前目錄(使用cd命令),然后鍵入下面的命令:
git init
如果你希望獲?。寺。﹦e人的倉(cāng)庫(kù),在命令下切換到希望克隆到的目錄下,鍵入下面命令:
git clone url [your repository name]
跟蹤某個(gè)文件
當(dāng)前的工作目錄下可能有很多個(gè)文件,有些是我們需要版本控制工具進(jìn)行版本控制的,比如我的代碼文件;但是也有一些是不需要進(jìn)行版本控制的,比如一些臨時(shí)文件。所以,當(dāng)我們創(chuàng)建了本地的倉(cāng)庫(kù)后,這個(gè)倉(cāng)庫(kù)是空的,需要我們自行決定什么文件需要被git追蹤,什么文件不需要被git追蹤。
想將一個(gè)文件納入追蹤系統(tǒng),可以鍵入以下命令:
git add filePath
對(duì)于不想追蹤的文件,可以創(chuàng)建一個(gè)名字為.gitignore的文件,把不想追蹤的文件或者子目錄列在里面。然后使用以下命令,把除了列出的不追蹤文件以外的其他文件,納入追蹤系統(tǒng)。
git add .
文件.gitignore的格式規(guī)范如下:
- 所有空行或者以 # 開頭的行都會(huì)被 Git 忽略
- 可以使用標(biāo)準(zhǔn)的 glob 模式匹配
- 匹配模式可以以(/)開頭防止遞歸
- 匹配模式可以以(/)結(jié)尾指定目錄
- 要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(hào)(!)取反
檢查當(dāng)前文件狀態(tài)
每當(dāng)我們?cè)谝呀?jīng)進(jìn)行了版本控制的文件夾下工作,我們對(duì)已跟蹤的所有文件的每一步操作都對(duì)被版本控制工具記錄。希望查詢,當(dāng)前的文件狀態(tài),可以使用命令:
git status
把當(dāng)前的更改提交到倉(cāng)庫(kù)
如果完成了一個(gè)階段的工作,需要把當(dāng)前的更改提交到倉(cāng)庫(kù),可以使用以下命令:
git commit -m "commit information"
小結(jié)
以上所述,就是一個(gè)基本的git工作流程:
- 創(chuàng)建本地倉(cāng)庫(kù)
- 決定追蹤的文件(可以使用.gitignore進(jìn)行批量操作)
- 對(duì)文件做各種修改(工作過(guò)程,和git無(wú)關(guān))
- 將修改后的文件提交到倉(cāng)庫(kù)里(倉(cāng)庫(kù)存的是當(dāng)前文件的一個(gè)快照,或者叫當(dāng)前文件的狀態(tài))
下面的圖片,描述了使用git時(shí),文件的生命周期:

例子
下面提供一個(gè)實(shí)現(xiàn)基本操作的例子:
- 在桌面創(chuàng)建一個(gè)名字為"example"的文件夾
- 將該目錄初始化為git工作目錄
- 在該目錄下添加一個(gè)
HelloWorld.java文件和一個(gè)ignore.txt文件,配置.ignore文件,使用批量添加命令,但是ignore.txt不加入版本管理(只加入HelloWorld.java) - 執(zhí)行
git add .命令 - 執(zhí)行
git commit -m "first commit"命令
鍵入初始化命令,完成倉(cāng)庫(kù)初始化后應(yīng)該如下圖所示:

添加三個(gè)文件后(這三個(gè)文件的內(nèi)容請(qǐng)見下文),該目錄下應(yīng)該有以下的內(nèi)容:

執(zhí)行 git add .命令后,只添加了HelloWrold.java:

執(zhí)行 git commit -m "first commit”命令:

//HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world version one");
}
}
//ignore.txt
this is a ignore file
//.gitignore
// ignore all the file contain "ignore" as substring as their name
*ignore*
commit前的修改
生活總不是美好的,有時(shí)候,在我們add完文件之后,發(fā)現(xiàn)添加了一些沒(méi)必要追蹤的文件。在沒(méi)有commit之前,我們?nèi)绾伟阉鼈內(nèi)サ裟??可以使用如下的命令(git也會(huì)給出提示):
git rm --cached fileName
commit補(bǔ)救
生活總不是美好的,有時(shí)候,我們?cè)赾ommit玩文件之后發(fā)現(xiàn),少add了一些文件,但是又不想重新創(chuàng)建一次commit,應(yīng)該怎么補(bǔ)救呢?重新添加完文件之后,可以使用如下的命令:
git commit --amend
如此一來(lái),本次的提交將會(huì)覆蓋掉上一次的提交。
撤銷操作
現(xiàn)在我們來(lái)修改一下剛剛寫的HelloWorld.java文件,把它改成如下所示:
//HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
// version one 改成了 version two
System.out.println("hello world version two");
}
}
然后,把這個(gè)更改add以及commit一下:

在未來(lái)的某一天,我突然發(fā)現(xiàn)我這個(gè)改動(dòng)是不對(duì)的,我希望回到version one的狀態(tài)?。?!不要想象這僅僅是一行代碼,想象你改變了很多東西,某一天發(fā)現(xiàn)某一次的改動(dòng)是不對(duì)的,你想返回之前的狀態(tài)!如果你沒(méi)有進(jìn)行版本管理的話,唯一的方法就是手動(dòng)返回,這個(gè)時(shí)候只能給你說(shuō)一聲good luck了。但是只要你之前曾經(jīng)進(jìn)行過(guò)版本管理,也就是說(shuō)你commit過(guò)的話,這一切就會(huì)變得非常簡(jiǎn)單。
使用如下命令,可以查看提交歷史:
git log

如果希望退回之前的版本,可以使用以下命令:
git reset --hard HEAD~n //n,表示退回的版本數(shù),也可以用版本號(hào)來(lái)代替“HEAD~n”
在git當(dāng)中,使用“HEAD”來(lái)表示當(dāng)前的版本,使用“HEAD~1”來(lái)表示前一次的版本,使用“HEAD~2”來(lái)表示前兩次的版本,使用“HEAD~100”來(lái)表示前100次版本。下面,我們來(lái)嘗試退回前一個(gè)版本看看。執(zhí)行,上述命令后,打開HelloWorld.java文件可以看到,果然退回去了,內(nèi)容如下:

現(xiàn)在問(wèn)題來(lái)了,我以為我上次做是對(duì)的,其實(shí)這次做的才是對(duì)的,但是我又已經(jīng)退回上一次的版本了,怎么破!沒(méi)關(guān)系,git來(lái)拯救你。由于,我們已經(jīng)退回去了,通過(guò)git log已經(jīng)查不到我的版本號(hào)了,怎么辦。git其實(shí)記錄我們所有的操作,通過(guò)以下命令,我們可以獲取到所有commit過(guò)的版本號(hào):
git reflog
我這里找到我第二次提交的版本號(hào)是:33ce596,我就可以通過(guò)以下命令,回到之前第二次提交的版本了:
git reset --hard 33ce596

以上,是本地使用git的最基礎(chǔ)方法,如何使用分支,以及遠(yuǎn)程倉(cāng)庫(kù)(例如著名的github),接下來(lái)的文章會(huì)有說(shuō)是,敬請(qǐng)期待。