最近在家太閑了,翻到以前學(xué)Git整理的筆記,簡(jiǎn)單的整理了一下,分享給大家。
一、Git簡(jiǎn)介和幾個(gè)概念
git是 Linus 使用使用C語言開發(fā)的,最初管理端是 Linux 的源碼。
集中式與分布式
-
集中式
代表:SVN、CVS(沒有SVN穩(wěn)定)、VSS(據(jù)說反人類,微軟自己都不用)

? 集中式版本控制系統(tǒng),其版本庫是放在中央服務(wù)器上的。這樣,每次使用前都需要從中央服務(wù)器中獲取最新版本;結(jié)束工作后再把當(dāng)天做完的工作推送給中央服務(wù)器。
特點(diǎn)(缺點(diǎn))
- 集中式版本控制系統(tǒng)最大的缺陷在于,必須聯(lián)網(wǎng)才可以進(jìn)行工作。這就涉及到工作環(huán)境的網(wǎng)絡(luò)和帶寬,如果是局域網(wǎng)還好;如果是互聯(lián)網(wǎng),其效率將會(huì)非常低下。
- 集中式的中央服務(wù)器如果出了問題,則所有人都沒法干活了。
-
分布式
代表:Git、 BitKeeper(收費(fèi))

? 分布式版本控制系統(tǒng),沒有所謂的“中央服務(wù)器”,其版本是放在每一個(gè)工作者的電腦中的,每個(gè)人的電腦都是一個(gè)完整的版本庫。
特點(diǎn)
- 不受網(wǎng)絡(luò)的限制,工作時(shí)不需要聯(lián)網(wǎng)。如果需要多人協(xié)作,則只需要將各自修改的內(nèi)容推送給對(duì)方即可。
- 沒有所謂的“中央服務(wù)器”是指沒有集中式那樣,需要完全依賴此的服務(wù)器。分布式版本控制系統(tǒng)會(huì)有一個(gè)僅僅是充當(dāng)“中介者”角色的服務(wù)器,方便多人協(xié)作時(shí),傳遞大家修改的信息。(即使沒有這樣的“中介者”,大家一樣可以做自己的工作,只是不方便相互修改而已。)
工作區(qū)、暫存區(qū)、版本庫
工作區(qū): 就是在電腦里能看到的目錄
暫存區(qū): 稱為stage(或者叫index),可以理解為工作區(qū)與版本分支中間的一個(gè)緩沖區(qū)。后面馬上提到
git add就是把修改的內(nèi)容,先添加到暫存區(qū)。等我們把所有要提交到倉(cāng)庫的內(nèi)容都添加到暫存區(qū)后,就可以用git commit來提交到指定分支啦。(當(dāng)然,你也可以每 add 一次,就 commit 一次)版本庫:指的就是工作區(qū)中的
.git文件夾,這個(gè)不算工作區(qū),而是Git的版本庫。

二、Git的基礎(chǔ)使用
1. 安裝后的基本配置
git在安裝完成后,需要進(jìn)行一些基礎(chǔ)的配置。
# 注意:這里使用了--global參數(shù),這樣設(shè)置會(huì)讓所在機(jī)器上的所有的Git倉(cāng)庫都是用這個(gè)配置(常規(guī)操作,安心設(shè)置就好)
# 設(shè)置名字
$ git config --global user.name "Your Name"
# 設(shè)置郵箱
$ git config --global user.email "email@example.com"
2. 創(chuàng)建第一個(gè)版本庫(本地)
版本庫也就是常說的倉(cāng)庫,可以簡(jiǎn)單理解成一個(gè)目錄。這個(gè)目錄里面的所有文件都可以被Git管理起來,每個(gè)文件的修改、刪除,Git都能跟蹤,以便任何時(shí)刻都可以追蹤歷史,或者在將來某個(gè)時(shí)刻可以“還原”。
找一個(gè)合適的地方,建一個(gè)空文件夾(也不一定是空的,項(xiàng)目寫完了再建倉(cāng)庫也行)(為了避免任何因?yàn)槁窂降腻e(cuò)誤,請(qǐng)確保文件夾路徑中沒有英文!)。然后在這個(gè)文件夾 單擊右鍵 → Git Bush Here,輸入:
$ git init
完事兒,以后倉(cāng)庫就建好了!

<u>劃重點(diǎn):</u> 如果你看到文件夾里有一個(gè)隱藏的、名叫.git的文件夾。注意!千萬不要?jiǎng)h他或者修改它,因?yàn)樗怯脕?/em>跟蹤管理版本庫的,認(rèn)為的修改可能會(huì)對(duì)倉(cāng)庫造成一些不必要的破壞。(如果沒看到也沒事兒,它本身就是隱藏的,說明你沒有打開顯示隱藏的文件夾(也不太需要打開了...))
3. 提交
-
把文件添加到暫存區(qū)
# 提交一個(gè)文件 $ git add index.html # 提交兩個(gè)文件 $ git add index-2.html index-3.html # 這一步,沒有提示!當(dāng)然,也可以一次添加所有的文件
# 提交所有變化(刪除、修改、新增) $ git add -A # 提交被修改(modified)和被刪除(deleted)文件,不包括新文件(new) $ git add -u # 提交新文件(new)和被修改(modified)文件,不包括被刪除(deleted)文件 $ git add . -
把剛才添加的文件提交到倉(cāng)庫
$ git commit -m "massage content" # -m 指的是massage,和之后見到的master無關(guān) # massage content 對(duì)本次提交內(nèi)容的說明

要注意的是:Git之所以比其他的版本控制系統(tǒng)優(yōu)秀,是因?yàn)镚it跟蹤和管理的并不是文件,而是你的每一行修改。因此,在我們對(duì)項(xiàng)目修改后,都要進(jìn)行
git add將修改添加到暫存區(qū)。如果沒有git add,直接進(jìn)行git commit是無法將代碼提交的本地倉(cāng)庫的。
4. 關(guān)注工作區(qū)狀態(tài)
4.1 使用 git status 隨時(shí)可以得知工作區(qū)的狀態(tài)
$ git status
-
在工作區(qū)沒有文件被修改的時(shí)候
-
在工作區(qū)有文件被修改的時(shí)候
- 我們直接輸入命令
git status,輸出的命令告知我們index.html文件有被修改但是沒有準(zhǔn)備提交,同時(shí)建議我們使用git add和git commit添加提交。
- 我們直接輸入命令

- 這時(shí)我們可以用
git diff查看哪里被修改了。減號(hào)開頭的代表修改前的,加號(hào)開頭代表修改后的。這里我們課看到,我加了一個(gè)感嘆號(hào)(其實(shí)感嘆號(hào)前還有個(gè)空格...)

- 這時(shí)候就可以使用
git add和git commit進(jìn)行提交了,提交完成后,再用git status就會(huì)發(fā)現(xiàn):nothing to commit, working directory clean。到此為止就完成了一次的修改及提交!
4.2 我忘了剛才修改的文件 git commit 提交版本庫了沒
這時(shí)候,同樣使用 git status 可以看出區(qū)別。



4.3 使用 git log 查看修改過的版本
# 展示所有的版本
$ git log
# 用一行展示每一個(gè)版本
$ git log --pretty=oneline
? 黃色的字符串(commit后面的)就是每個(gè)版本的版本號(hào),可以理解為每個(gè)版本的id,是一個(gè)十六進(jìn)制的超長(zhǎng)的數(shù)字。當(dāng)我們通過git操作版本的時(shí)候,需要用到這個(gè)版本號(hào)。不過看見這么長(zhǎng)也不用怕,我們不需要全部都寫出來,一般寫7位能讓Git找到即可。

5. 回退版本
在我們回退版本之前,我們需要先明確一個(gè)概念—— HEAD
5.1 HEAD
Git中, HEAD 是一個(gè)指針,它指向表示當(dāng)前的版本。所以在回退版本時(shí),也就是對(duì) HEAD 指向進(jìn)行改變。
- 如果我們需要回退到上一個(gè)版本,就是
HEAD^;回退到上上一個(gè)版本,就是HEAD^^。 - 如果回退更多版本,就可以使用
HEAD~數(shù)字的方式,例如HEAD~100就是回退100個(gè)版本;HEAD~1就是回退1個(gè)版本。
5.2 穿越到過去
三種方式都可以,最后一種記得修改commit_id的值(這個(gè)值是啥?看上面4.3?。?/p>
# 回退1個(gè)版本
$ git reset --hard HEAD^
# 回退10個(gè)版本
$ git reset --hard HEAD~10
# 回退指定版本號(hào)的版本
$ git reset --hard commit_id
<u>注:</u> 中間的 --hard 是回退的方式,一共有三種,我們后面在單獨(dú)討論他們的區(qū)別,先放心這樣用就好。

完成以后,我們發(fā)現(xiàn)命令回復(fù)給我們一行提示,看到這樣的提示,就代表我們回退成功了。其中:
-
HEAD就是我們前面說的指針(is now at就不用我說了吧) -
2c76e6a就是回退后的版本號(hào)的前7位(知道為啥前面說是7位了吧) -
index就是這個(gè)版本的描述,我這里對(duì)這個(gè)版本的描述就是index
5.3 穿越到未來
當(dāng)我們回退版本(版本A)以后,又想回到我們回退之前的版本(版本B),該怎么辦?
我們還是使用 git reset 命令來解決問題,但是這時(shí)只能使用 commit_id 來進(jìn)行“穿越”。但是,這時(shí)候我們使用 git log 查找版本號(hào)時(shí),發(fā)現(xiàn)只有版本A以前的版本。

這時(shí)候,我們就要用到另一個(gè)命令,來找到我們版本B的版本號(hào)。它可以告訴我們,我們對(duì)版本庫進(jìn)行了那些操作。有這個(gè)命令,即時(shí)我們關(guān)機(jī)重啟,也可以找到我們所有的操作記錄。
$ git reflog

很顯然,在版本 2c76e6a (版本A)之后的版本 4cefb07 (版本B)就是我們想穿越到未來的版本。這時(shí)候我們只需要使用版本號(hào)來進(jìn)行“穿越”即可。
$ git reset --hard 4cefb07
6. 撤銷修改
當(dāng)我們修改之前的代碼的時(shí)候,難免會(huì)出現(xiàn)改著改著就改亂了的情況。這時(shí)候我們第一時(shí)間是想撤銷修改,但是一直 Ctrl Z 未免也太累了吧。這時(shí)候,就是使用Git的一些命令來解決問題。不過,我們要分幾種場(chǎng)景。
(不知道場(chǎng)景狀態(tài)的,請(qǐng)看4.2)
6.1 文件只是在工作區(qū)修改,還沒有 git add ,想撤銷
直接使用以下命令,把文件在工作區(qū)的修改全部撤銷。這時(shí)候也就撤銷到和當(dāng)前版本庫一毛一樣的狀態(tài)了。
$ git checkout -- 文件名
# 注意空格和 -- 不可以少!否則就是切換分支(git checkout)的命令了
# 這個(gè)命令的目的,就是讓這個(gè)文件回到最近一次git commit或git add時(shí)的狀態(tài)。
6.2 文件已經(jīng) git add 到暫存區(qū),工作區(qū)發(fā)生了修改,想撤銷到暫存區(qū)的版本狀態(tài)
-
第一步:用下面的命令撤銷暫存區(qū)的修改,用HEAD代表本地倉(cāng)庫的最新版本
$ git reset HEAD 文件名 第二步,重復(fù)6.1的操作
最后我們還可以用
git status來檢查一下,看看命令行的反饋是不是和下面一樣:

6.3 文件已經(jīng) git commit 到版本庫,想撤銷修改
假設(shè)你不但改錯(cuò)了東西,還從暫存區(qū)提交到了版本庫,怎么辦呢?
是不是感覺這個(gè)場(chǎng)景有點(diǎn)似曾相識(shí),沒錯(cuò),其實(shí)就是把我們的倉(cāng)庫版本回退一下就可以了。
不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠(yuǎn)程(遠(yuǎn)程倉(cāng)庫后面再說)。如果你已經(jīng)推到遠(yuǎn)程倉(cāng)庫了,就么得辦法了~~
7. 刪除文件
一般情況下,你通常直接在文件管理器中把沒用的文件刪了,這里我刪除了 index.html 。 這個(gè)時(shí)候,Git知道我刪除了文件,因此,工作區(qū)和版本庫就不一致了,git status命令會(huì)立刻告訴你哪些文件被刪除了:

現(xiàn)在你有兩個(gè)場(chǎng)景:
-
一是確實(shí)要從版本庫中刪除該文件,那就用命令
git rm刪掉,并且git commit:$ git rm index.html # 這一步也可以用git add index.html進(jìn)行 $ git commit -m "delete"這樣就把文件從版本庫中刪除了。
二是誤刪了,但是版本庫里本身有這個(gè)文件,那完全可以用
$ git checkout -- 文件名來恢復(fù)。但是!如果這個(gè)文件本身沒有被添加到版本庫,那就趕緊去回收站里看看吧,Git是沒有辦法幫你了...
參考資料 廖雪峰 - Git