1.初始化本地倉(cāng)庫(kù)
1
gitinit
2.添加文件到本地倉(cāng)庫(kù)暫存區(qū)
1
gitadda.txt
3.添加文件到本地倉(cāng)庫(kù)
1
gitcommit-m'v1'
此命令代表確認(rèn)提交到本地倉(cāng)庫(kù)。-m ‘v1’代表為此添加一個(gè)版本標(biāo)記v1
4.查看當(dāng)前git的狀態(tài)
1
gitstatus
結(jié)果A:
1
2
3
4
5
6
7
8Onbranchmaster
Changesnotstagedforcommit:
(use"git add ..."toupdatewhatwillbecommitted)
(use"git checkout -- ..."todiscardchangesinworkingdirectory)
modified:readme.txt
nochangesaddedtocommit(use"git add"and/or"git commit -a")
證明當(dāng)前有文件已經(jīng)修改,但是沒有準(zhǔn)備提交的修改,沒有add和commit
結(jié)果B:
1
2
3
4
5Onbranchmaster
Changestobecommitted:
(use"git reset HEAD ..."tounstage)
modified:readme.txt
證明當(dāng)前已經(jīng)有文件提交了,但是還沒有commit
結(jié)果C:
1
2Onbranchmaster
nothingtocommit,workingdirectoryclean
證明當(dāng)前所有文件已經(jīng)提交到本地倉(cāng)庫(kù),工作目錄是干凈的
5.查看git日志
1
gitlog
結(jié)果:
1
2
3
4
5
6
7
8
9
10
11commitaca3fe6cc3f49ded922d05e4774561f33697f710
Author:QingcaiCui<1016903103@qq.com>
Date:SunNov212:16:252014+0800
v2
commit90eea044b6da3818770ec482df98bb05ab569472
Author:QingcaiCui<1016903103@qq.com>
Date:SunNov212:07:462014+0800
v1
證明當(dāng)前我們已經(jīng)commit了兩次,上面的為最近提交的。
如果嫌輸出太多可以嘗試下面的命令,一行顯示
1
gitlog--pretty=oneline
結(jié)果如下:
1
2aca3fe6cc3f49ded922d05e4774561f33697f710v2
90eea044b6da3818770ec482df98bb05ab569472v1
一大串類似的
1
aca3fe6cc3f49ded922d05e4774561f33697f710
是commit id(版本號(hào)),和SVN不一樣,Git的 commit id 不是1,2,3……遞增的數(shù)字,而是一個(gè)SHA1計(jì)算出來(lái)的一個(gè)非常大的數(shù)字,用十六進(jìn)制表示,而且你看到的commit id和我的肯定不一樣,以你自己的為準(zhǔn)。為什么commit id需要用這么一大串?dāng)?shù)字表示呢?因?yàn)镚it是分布式的版本控制系統(tǒng),后面我們還要研究多人在同一個(gè)版本庫(kù)里工作,如果大家都用1,2,3……作為版本號(hào),那肯定就沖突了。
6.版本回退
回退到上一版本:
1
gitreset--hardHEAD^
回退到上上個(gè)版本:
1
gitreset--hardHEAD^^
如果回退的版本過多則不用加那么多的^號(hào)
比如回退到上10版本,則可以用下面的命令
1
gitreset--hardHEAD~10
回退1個(gè)版本相當(dāng)于
1
gitreset--hardHEAD~1
不過現(xiàn)在利用git status來(lái)查看已經(jīng)看不到剛才那個(gè)版本了,想要返回的話怎么辦
可以仍然用上面的方法
1
gitreset--hardaca3f
只要寫前幾位就好了,git會(huì)自動(dòng)去匹配的。當(dāng)然前提是你的命令行窗口沒有關(guān)閉還能找到之前的commit id。
不過萬(wàn)一你的命令行關(guān)閉了也沒關(guān)系,git提供了一個(gè)方法來(lái)記錄你的每一次命令。
1
gitreflog
結(jié)果:
1
2
3
4aca3fe6HEAD@{0}:reset:movingtoaca3f
90eea04HEAD@{1}:reset:movingtoHEAD^
aca3fe6HEAD@{2}:commit:jj
90eea04HEAD@{3}:commit(initial):aa
在前方仍然顯示了版本號(hào),你仍然可以找到。仍然可以利用的reset命令來(lái)還原。
注意:
A 工作區(qū)和暫存區(qū)的名詞區(qū)別
工作區(qū):就是你在電腦里能看到的目錄
暫存區(qū):在.git文件夾下存在一個(gè)暫存區(qū)stage和好多個(gè)分支比如master
當(dāng)執(zhí)行g(shù)it add命令時(shí),工作區(qū)的內(nèi)容便會(huì)到stage暫存區(qū)中,當(dāng)執(zhí)行g(shù)it commit命令時(shí)暫存區(qū)的內(nèi)容便會(huì)提交到分支里面。
B “Git管理的是修改”的意思
比如第一次修改readme.txt,然后執(zhí)行g(shù)it add到暫存區(qū),然后再修改readme.txt,然后執(zhí)行g(shù)it commit 到分支。
結(jié)果調(diào)用 git status 時(shí)發(fā)現(xiàn)現(xiàn)在仍然有一個(gè)modified文件,這是因?yàn)槲覀儧]有把新修改的文件提交到暫存區(qū),所以導(dǎo)致分支中的文件和在工作區(qū)的原文不匹配。所以我們需要重新add和commit。這說明git管理的是”修改”,而不是”文件”本身。
7.撤銷修改
1
gitcheckout--filename
比如 git checkout — readme.txt 它的作用如下:
把?readme.txt?文件在工作區(qū)的修改全部撤銷,這里有兩種情況:
一種是?readme.txt?自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫(kù)一模一樣的狀態(tài);
一種是?readme.txt?已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)。
總之,就是讓這個(gè)文件回到最近一次?git commit?或?git add?時(shí)的狀態(tài)。
那么上面的這個(gè)情況是我們提交或者沒提交到暫存區(qū)之后又對(duì)源文件做的修改。
還有另一種情況,我們提交之后放到了暫存區(qū),我們想把暫存區(qū)里面的文件撤銷回來(lái)。
就用以下命令:
1
gitresetHEADreadme.txt
就是將剛才的git add命令撤銷,把暫存區(qū)中的內(nèi)容撤銷回到工作區(qū)。
當(dāng)然,如果你不但add了,并且又commit了,那就只能進(jìn)行版本回退了。在上面已經(jīng)說過了。
總結(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 file,就回到了場(chǎng)景1,第二步按場(chǎng)景1操作。
場(chǎng)景3:已經(jīng)提交了不合適的修改到版本庫(kù)時(shí),想要撤銷本次提交,進(jìn)行版本回退,不過前提是沒有推送到遠(yuǎn)程庫(kù)。
8.刪除文件
假如現(xiàn)在你新建了一個(gè) hello.txt 文件,你已經(jīng)add并commit到了本地分支之中。
現(xiàn)在你想刪除,如果直接執(zhí)行
1
rmhello.txt
則是只把工作區(qū)中的文件刪除了,本地分支中沒有刪除,現(xiàn)在你執(zhí)行g(shù)it status 則會(huì)提示當(dāng)前工作區(qū)已刪除了一個(gè)文件,本地分支仍然存在,就存在了工作區(qū)和本地分支不同步的問題,現(xiàn)在我們?nèi)绻牖謴?fù)一下,就利用下面的命令
1
gitcheckout--hello.txt
將本地的文件一鍵還原。
假如我們真的是想將本地分支中的一個(gè)文件刪除,那么我們就執(zhí)行下面的方法。
1
gitrmhello.txt
執(zhí)行了這個(gè)命令之后,我們執(zhí)行 git status 之后就會(huì)提示 你現(xiàn)在需要commit一下確認(rèn)刪除。
并且執(zhí)行完這個(gè)命令之后,我們執(zhí)行 ls 命令之后發(fā)現(xiàn)本地的文件也已經(jīng)不存在了。
如果有很多個(gè)文件在本地被刪除掉了,暫存區(qū)和工作區(qū)的文件完全不一樣了,工作區(qū)刪除掉了很多個(gè)文件,就會(huì)出現(xiàn)
1
2
3Changesnotstagedforcommit:
deleted:a.txt
deleted:b.txt
如果一個(gè)個(gè)地刪除文件肯定特別麻煩,所以我們可以用下面的命令來(lái)
1
gitadd-A
它等同于
git add . 和 git add -u
1
gitadd.保存所有新文件和改動(dòng)的文件,不包括刪除的文件
1
gitadd-u保存所有改動(dòng)的文件和刪除的文件,不包括新的文件
git add -A 和 git add -u 會(huì)把我們未通過 git rm 刪除的文件全部stage 使用過以后運(yùn)行 git status 便會(huì)出現(xiàn) changes to be committed … 說明已經(jīng)都經(jīng)過git rm 刪除了. 綜上,我們想刪除分支中的文件時(shí)就需要兩條命令合起來(lái)使用
1
2gitrmhello.txt
gitcommit-m'rm hello.txt'
要小心的是,執(zhí)行 git rm 方法之后工作區(qū)和本地分支中的文件已經(jīng)都不存在了。所以如果你已經(jīng)在遠(yuǎn)程倉(cāng)庫(kù)存在備份的話,你就不用擔(dān)心誤刪了。否則你就要小心了,會(huì)丟失這個(gè)文件的。 對(duì)比修改的文件
1
gitdiff
結(jié)果:
1
2
3
4
5
6
7diff--gita/readme.txtb/readme.txt
index9c58532..8ce5f7e100644
---a/readme.txt
+++b/readme.txt
@@-1+1@@
-gitisgrea
+helloisgrea
-號(hào)開頭的語(yǔ)句代表這句話刪除掉了 +號(hào)開頭的語(yǔ)句代表這句話為新增語(yǔ)句 9.分支 新建本地分支
1
gitbranchdev
切換到dev分支
1
gitcheckoutdev
創(chuàng)建并切換到該分支
1
gitcheckout-bdev
查看本地分支
1
gitbranch
比如此命令會(huì)輸出 * master hello 代表當(dāng)前已經(jīng)選中了master分支,存在本地兩個(gè)分支master和hello 合并分支
1
2gitbranchmaster
gitmergehello
這樣我們就把 master 分支合并到了hello分支了。 接下來(lái)我們就可以刪除本地分支了。 既然分支合并這么簡(jiǎn)單,它可不可能出現(xiàn)什么問題呢?當(dāng)然有,當(dāng)然會(huì)出現(xiàn)分支合并沖突的問題。 比如我切換到了hello分支并修改了一個(gè)文件 add并且commit,然后我切換回了master分支 同樣修改了這個(gè)文件,add并且commit?,F(xiàn)在我們?nèi)绻麍?zhí)行g(shù)it merge hello 則會(huì)報(bào)一個(gè)提示說 分支合并沖突。 我們查看剛才修改的文件發(fā)現(xiàn)已經(jīng)發(fā)生了變化,我們需要手動(dòng)修改完了之后,然后繼續(xù)add和commit才可以。如果沒有add和commit,那么我們無(wú)法切換回原來(lái)的分支的。 add和commit之后,原來(lái)的hello分支仍然保持了原來(lái)不變,只不過是我們的master分支改變了。下面示意圖則清楚地表示出了如下關(guān)系,圖中的feature1相當(dāng)于hello分支。 合并之后,我們就可以進(jìn)行刪除分支了,可以刪除掉hello分支。其實(shí)上面的一系列操作 從merge到修改 然后add 然后commit 其實(shí)可以利用一條命令來(lái)修改,這個(gè)方法叫禁用Fast Forward模式 剛才的一系列命令如下
1
2
3
4
5gitcheckoutmaster
gitmergehello
vifile.txt
gitaddfile.txt
gitcommit-m'merge master'
那么利用下面的語(yǔ)句同樣可以達(dá)成同樣的效果
1
2gitcheckoutmaster
gitmerge--no-ff-m'merge master'hello
因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建一個(gè)新的commit,所以加上 -m 參數(shù),把commit描述寫進(jìn)去。 Git就會(huì)在merge時(shí)生成一個(gè)新的commit,這樣,從分支歷史上就可以看出分支信息。 結(jié)束之后我們照樣可以刪除hello分支。 刪除本地分支
1
gitbranch-dhello
查看遠(yuǎn)程分支
1
gitbranch-r
查看本地和遠(yuǎn)程分支
1
gitbranch-a
現(xiàn)在遇到一個(gè)問題,我們正在工作的一個(gè)分支還沒有做完,不能add或者commit,但是現(xiàn)在有一個(gè)bug需要在另一個(gè)分支上去修復(fù),那么我們就需要暫時(shí)存儲(chǔ)當(dāng)前的分支。所以就要用到下面的命令
1
gitstash
當(dāng)我們處理完其他的事情之后,再切換回來(lái)此分支。 先使用
1
gitstashlist
再取出stash列表中的內(nèi)容
1
gitstashpop
上面的方法既取出了list內(nèi)容,并且把list中的元素刪除掉。 強(qiáng)行刪除分支
1
gitbranch-Dnew-branch
10.多人協(xié)作 多人協(xié)作的工作模式通常是這樣: 首先,可以試圖用
1
gitpushoriginbranch-name
推送自己的修改; 如果推送失敗,則因?yàn)檫h(yuǎn)程分支比你的本地更新,需要先用git pull試圖合并; 如果合并有沖突,則解決沖突,并在本地提交; 沒有沖突或者解決掉沖突后,再用
1
gitpushoriginbranch-name
推送就能成功! 如果git pull提示“no tracking information”,則說明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建,用命令
1
gitbranch--set-upstreambranch-nameorigin/branch-name
這就是多人協(xié)作的工作模式,一旦熟悉了,就非常簡(jiǎn)單。 11.添加遠(yuǎn)程地址別名
1
gitremoteaddorigingit@github.com
刪除遠(yuǎn)程地址別名
1
gitremotermorigin
此方法刪除掉origin這個(gè)地址別名
查看遠(yuǎn)程地址別名
1
gitremote-v
推送到遠(yuǎn)程分支
我們?cè)趃ithub上新建一個(gè)項(xiàng)目
添加遠(yuǎn)程倉(cāng)庫(kù)
1
gitremoteaddorigingit@github.com:cqcre/gittest.git
推送上去
1
gitpush-uoriginmaster
加上了?-u?參數(shù),Git不但會(huì)把本地的?master?分支內(nèi)容推送的遠(yuǎn)程新的?master?分支,還會(huì)把本地的?master?分支和遠(yuǎn)程的?master?分支關(guān)聯(lián)起來(lái),即相當(dāng)于推送到了一個(gè)默認(rèn)的分支,在以后的推送或者拉取時(shí)就可以簡(jiǎn)化命令。
那么以后我們就不需要關(guān)聯(lián)了,以后推送的話我們只需要輸入
1
gitpushoriginmaster
克隆遠(yuǎn)程倉(cāng)庫(kù)
假設(shè)現(xiàn)在已經(jīng)存在了一個(gè)遠(yuǎn)程倉(cāng)庫(kù),我們需要把這個(gè)倉(cāng)庫(kù)克隆到本地,我們需要使用下面的方法
1
gitclonegit@github.com:cqcre/test.git
這樣我們就把遠(yuǎn)程的一個(gè)倉(cāng)庫(kù)取到了本地了。
12.強(qiáng)制操作
強(qiáng)制覆蓋本地分支內(nèi)容
1
2gitfetch--all
gitreset--hardorigin/master
強(qiáng)制覆蓋遠(yuǎn)程內(nèi)容
1
gitpushoriginmaster--force
13.修改commit的備注
有時(shí)候我們commit的備注寫錯(cuò)了,需要重新修改,可以利用如下命令
1
gitcommit--amend
.gitignore的使用
在git中如果想忽略掉某個(gè)文件,不讓這個(gè)文件提交到版本庫(kù)中,可以使用修改根目錄中 .gitignore 文件的方法(如無(wú),則需自己手工建立此文件)。這個(gè)文件每一行保存了一個(gè)匹配的規(guī)則例如:
1
2
3
4
5*.a# 忽略所有 .a 結(jié)尾的文件
!lib.a# 但 lib.a 除外
/TODO# 僅僅忽略項(xiàng)目根目錄下的 TODO 文件,不包括 subdir/TODO
build/# 忽略 build/ 目錄下的所有文件
doc/*.txt# 會(huì)忽略 doc/notes.txt 但不包括 doc/server/arch.txt
規(guī)則很簡(jiǎn)單,不做過多解釋,但是有時(shí)候在項(xiàng)目開發(fā)過程中,突然心血來(lái)潮想把某些目錄或文件加入忽略規(guī)則,按照上述方法定義后發(fā)現(xiàn)并未生效,原因是.gitignore只能忽略那些原來(lái)沒有被track的文件,如果某些文件已經(jīng)被納入了版本管理中,則修改.gitignore是無(wú)效的。那么解決方法就是先把本地緩存刪除(改變成未track狀態(tài)),然后再提交:
1
2
3gitrm-r--cached.
gitadd.
gitcommit-m'update .gitignore'
打tag
在發(fā)布版本的時(shí)候,經(jīng)常會(huì)用到打標(biāo)簽的方法。
增加一個(gè)標(biāo)簽
1
gittag-a"v1.0.0"-m"Version 1.0.0"
刪除一個(gè)標(biāo)簽
1
gittag-dv1.0.0
推送所有標(biāo)簽
1
gitpushorigin--tags
刪除未監(jiān)視文件
1
2
3
4
5
6
7
8
9
10
11
12gitclean-f
# 連 untracked 的目錄也一起刪掉
gitclean-fd
# 連 gitignore 的untrack 文件/目錄也一起刪掉 (慎用,一般這個(gè)是用來(lái)刪掉編譯出來(lái)的 .o之類的文件用的)
gitclean-xfd
# 在用上述 git clean 前,墻裂建議加上 -n 參數(shù)來(lái)先看看會(huì)刪掉哪些文件,防止重要文件被誤刪
gitclean-nxfd
gitclean-nf
gitclean-nfd