概述
Git是一個(gè)用來做代碼管理和版本控制的工具。
參考教程
《Git權(quán)威指南》界拦,機(jī)械工業(yè)出版社吸申,蔣鑫。
如有理解錯(cuò)誤享甸,歡迎指正截碴。
總覽
版本控制工具的發(fā)展
1.diff和patch。
2.CVS蛉威。
3.SVN日丹。
4.Git。
Git初始化
git配置文件位置瓷翻。
? - 全局配置:/etc/gitconfig
? - 個(gè)人配置:~/.gitconfig
? - 具體Git庫配置:/path/to/repo/.git/config
使用git config配置用戶名和郵箱聚凹,--global表示當(dāng)前用戶。
git config --global user.name "Ruochen Xu"
git config --global user.email "ruochen.xu@aorise.com"
使用git config配置操作別名齐帚,可以讓指令變短妒牙,--system表示所有用戶。
git config --system alias.st status
注意:git config后的配置項(xiàng)都以a.b的形式表示对妄。使用--unset刪除配置湘今。
使用git init創(chuàng)建空的本地git庫,創(chuàng)建完成后剪菱,在庫目錄下有一個(gè).git文件夾摩瞎,里面存儲(chǔ)了與本git庫相關(guān)的所有信息拴签。
cd /path/to/my/workspace
git init demo
生成一個(gè)新文件,并使用git add加入暫存區(qū)旗们,然后使用git commit作一次的提交蚓哩。
提交可以看做是一個(gè)確認(rèn)的代碼改動(dòng)。
cd demo
echo "Hello." > readme.md
git add readme.md
git commit -m "Initialize.”
Git對(duì)象
Git中每個(gè)文件上渴、每次提交岸梨、每個(gè)目錄樹等信息,都是以git對(duì)象的形式存儲(chǔ)在庫的.git/objects目錄下的稠氮。每個(gè)git對(duì)象都有一個(gè)40位的SHA1哈希值曹阔,存儲(chǔ)時(shí)前兩位作為目錄名,后38位作為文件名隔披。
git cat-file -t <hash> # 查看git對(duì)象類型
git cat-file -p <hash> # 查看git對(duì)象內(nèi)容
Git分支
Git進(jìn)行第一次提交后赃份,會(huì)自動(dòng)生成第一個(gè)分支,也是默認(rèn)分支奢米,名稱為master抓韩。
每次git commit提交都可以看做是一個(gè)點(diǎn),相鄰的提交之間有邊相連鬓长,git每個(gè)提交都是增量的园蝠。每個(gè)提交都對(duì)應(yīng)有一個(gè)文件目錄樹,代表的是從第一次提交開始到該提交結(jié)束痢士,庫中的文件。
每個(gè)分支就是一個(gè)指向某個(gè)提交的指針茂装,代表著從第一次提交開始到該提交結(jié)束所有的文件變化歷程怠蹂。每個(gè)分支應(yīng)當(dāng)有一個(gè)獨(dú)有的名字,HEAD表示當(dāng)前正在操作的提交少态。
新的提交只能在某個(gè)分支上進(jìn)行城侧,即HEAD指針停留在某個(gè)分支指針上,而不能在任意提交上進(jìn)行彼妻。
新分支可以從某個(gè)提交處產(chǎn)生嫌佑,舊分支也可以與別的分支合并然后刪除。所以所有的提交構(gòu)成一張圖侨歉。
Git的分支信息都存儲(chǔ)在庫的.git/refs/heads目錄下屋摇,庫的.git/HEAD文件存儲(chǔ)HEAD指針的信息,庫的.git/logs/refs/heads目錄下記錄了分支的變化歷史幽邓。
Git提交的相對(duì)訪問
^炮温,父提交,^2牵舵,第二個(gè)父提交柒啤,例如HEAD^2倦挂。
~n,第n個(gè)祖先提交担巩,例如HEAD~5方援。
^{tree},提交所對(duì)應(yīng)的目錄樹涛癌,例如HEAD^{tree}犯戏。
:path/to/file,提交所對(duì)應(yīng)的目錄樹中的文件祖很,例如HEAD:path/to/file笛丙,不帶分支名時(shí)指的是暫存區(qū)中的文件。
Git分支操作
分支移動(dòng)假颇。
git commit # 進(jìn)行一次提交并將當(dāng)前分支移動(dòng)到新的提交
git reset <commit> # 將當(dāng)前分支移動(dòng)到指定提交
分支查看胚鸯。
git branch -a
HEAD指針切換。
git checkout <commit>
從當(dāng)前位置創(chuàng)建新分支笨鸡。
git checkout -b <branch>
分支合并姜钳。
git merge <commit>
分支刪除。
git branch -d <branch>
Git庫類型
Git庫主要分為三種類型形耗。
1.bare哥桥,可讀寫的主庫,一般放在遠(yuǎn)端服務(wù)器上激涤,并設(shè)置成不能撤銷寫入的模式拟糕。不能在bare庫本地直接對(duì)bare庫進(jìn)行操作。
2.mirror倦踢,可讀不可寫的bare庫鏡像送滞,一般放在遠(yuǎn)端服務(wù)器上,也可以放在開發(fā)機(jī)上辱挥±缧幔可以在mirror庫本地操作其與bare庫進(jìn)行同步。
3.local晤碘,可以任意操作的本地庫褂微,放在開發(fā)機(jī)上≡耙可以與遠(yuǎn)端的bare宠蚂、mirror庫進(jìn)行交互操作。
Git庫的常規(guī)操作流程
1.使用git clone克隆遠(yuǎn)端bare庫或者mirror庫到本地腮介,此時(shí)遠(yuǎn)端bare庫默認(rèn)使用origin這個(gè)名稱肥矢。也可以使用git remote add將本地已初始化的庫關(guān)聯(lián)到遠(yuǎn)端bare庫或者mirror庫。
git clone git@github.com:hnxuruochen/test.git
git remote add origin git@github.com:hnxuruochen/test.git
注意:每個(gè)local庫都可以有任意多個(gè)遠(yuǎn)端關(guān)聯(lián)庫,用不同的名稱區(qū)分甘改,origin是默認(rèn)名稱旅东。
2.使用git pull將遠(yuǎn)端bare或者mirror庫的指定分支的最新改動(dòng)拉到本地當(dāng)前分支。如果分支之間有沖突則需要進(jìn)行沖突解決和分支合并十艾。
git pull = git fetch + git merge
git pull origin <branch>
3.使用git push將本地庫的當(dāng)前分支的最新改動(dòng)推到遠(yuǎn)端bare庫的指定分支抵代。如果分支之間有沖突則需要先通過git pull解決沖突并合并分之后,才能繼續(xù)push忘嫉。
git push origin <branch>
團(tuán)隊(duì)一般通過一個(gè)bare庫荤牍,每人一個(gè)local庫的方式進(jìn)行合作開發(fā)。
Git文件區(qū)
Git庫本地分為三個(gè)文件區(qū)庆冕。
1.工作區(qū)康吵。存放本地文件的文件系統(tǒng),對(duì)文件的改動(dòng)都是在工作區(qū)完成的访递。
2.暫存區(qū)晦嵌。用于記錄和追蹤文件狀態(tài)的臨時(shí)區(qū),庫的.git/index記錄的就是暫存區(qū)的目錄樹拷姿。
3.版本庫惭载。存放確定文件改動(dòng)的庫。所有的提交响巢、分支都是在版本庫中的描滔,bare、mirror庫與local庫的交互實(shí)際上是版本庫的交互踪古。
提交文件只能從工作區(qū)到暫存區(qū)含长,或者暫存區(qū)到版本庫。還原文件只能從版本庫到暫存區(qū)伏穆,或者暫存區(qū)到工作區(qū)茎芋。不能跨區(qū)操作。
文件區(qū)之間的操作
文件狀態(tài)蜈出。
git status
文件比較。
git diff # 比較工作區(qū)與暫存區(qū)
git diff HEAD # 比較工作區(qū)與版本庫中的當(dāng)前提交
git diff --cached?HEAD # 比較暫存區(qū)與版本庫中的當(dāng)前提交
文件提交涛酗。
git add?<file> # 從工作區(qū)到暫存區(qū)
git commit # 從暫存區(qū)到版本庫的新提交
文件還原铡原。
git checkout -- <file> # 從暫存區(qū)到工作區(qū)
git reset HEAD # 從版本庫中的當(dāng)前提交到暫存區(qū)
git checkout HEAD <file> # 從版本庫中的當(dāng)前提交到暫存區(qū)再到工作區(qū)
文件刪除。
git rm <file> # ?刪除工作區(qū)和暫存區(qū)中的文件
git rm --cached <file> # 只刪除暫存區(qū)的文件
git clean # 刪除工作區(qū)中未加入版本庫的文件
Git存放處
Git還有一個(gè)特殊的文件區(qū)叫做stash商叹,是用來臨時(shí)存放當(dāng)前工作區(qū)和暫存區(qū)的改動(dòng)的燕刻。
每次存放相當(dāng)于是作了一次不被實(shí)際應(yīng)用的提交,然后記錄在庫的.git/refs/stash中剖笙,存放的變化存放在庫的.git/logs/refs/stash中卵洗。
存儲(chǔ)并撤銷當(dāng)前工作區(qū)和暫存區(qū)的改動(dòng)。
git stash
恢復(fù)工作區(qū)和暫存區(qū)的改動(dòng)。
git stash pop
查看所有存放的改動(dòng)过蹂。
git stash list
Git里程碑
Git里程碑是人為對(duì)提交進(jìn)行的命名十绑。里程碑相關(guān)信息存儲(chǔ)在庫的,git/refs/tags目錄下。
里程碑分類
1.輕量級(jí)里程碑酷勺,創(chuàng)建時(shí)使用-l參數(shù)本橙。該里程碑本質(zhì)上是一個(gè)提交,但是沒有創(chuàng)建者信息脆诉。
2.帶說明的里程碑甚亭,創(chuàng)建時(shí)使用-a或-m參數(shù)。該里程碑式一個(gè)tag對(duì)象击胜。
3.帶簽名的里程碑亏狰,創(chuàng)建時(shí)使用參數(shù)-s或者-u。該里程碑也是一個(gè)tag對(duì)象偶摔,還添加了GnuPG簽名暇唾。
里程碑操作
顯示里程碑。
git tag
創(chuàng)建里程碑啰挪。
git tag <name>
刪除里程碑信不。
git tag -d <name> # 刪除本地
git push <remote> :<name> # 刪除遠(yuǎn)程
推送里程碑。
git push <remote> <name>
Git子模塊
Git庫可以將其他git庫作為子模塊引入亡呵。
創(chuàng)建子模塊抽活。
git submodule add <repo_path> <submodule_path>
初始化子模塊。
git submodule init
更新子模塊锰什。
git submodule update
查看子模塊下硕。
git submodule status
其他
文件忽略
可以通過編輯.gitignore文件來讓git忽略一些僅在工作區(qū)中的文件,.gitignore文件可以放在任意目錄下汁胆,對(duì)當(dāng)前目錄和子目錄生效梭姓。
一些復(fù)雜的分支操作
git cherry-pick,將指定提交的增量改動(dòng)應(yīng)用到當(dāng)前提交上嫩码。
git rebase誉尖,將指定的一段連續(xù)的增量提交應(yīng)用到指定提交上。
git revert铸题,使用一個(gè)新提交的方式撤銷上一個(gè)提交的內(nèi)容铡恕。
文件追溯
git blame指令可以追溯一個(gè)文件的改動(dòng)歷史信息。