實(shí)戰(zhàn)Git
作者:BrianXia
轉(zhuǎn)載請注明 http://www.reibang.com/p/ed034b004255
1甘桑、Git 介紹
Git是一個(gè)開源的分布式版本控制系統(tǒng)晓猛,用于敏捷高效地處理任何或小或大的項(xiàng)目。
Git 是 Linus Torvalds 為了幫助管理 Linux 內(nèi)核開發(fā)而開發(fā)的一個(gè)開放源碼的版本控制軟件胳嘲。
Git 與常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本庫的方式瘟则,不必服務(wù)器端軟件支持肃弟。
1.1 、Git 與 SVN 區(qū)別
GIT不僅僅是個(gè)版本控制系統(tǒng)桃煎,它也是個(gè)內(nèi)容管理系統(tǒng)(CMS),工作管理系統(tǒng)等篮幢。
如果你是一個(gè)具有使用SVN背景的人,你需要做一定的思想轉(zhuǎn)換为迈,來適應(yīng)GIT提供的一些概念和特征三椿。
Git 與 SVN 區(qū)別點(diǎn):
1、GIT是分布式的葫辐,SVN不是:這是GIT和其它非分布式的版本控制系統(tǒng)搜锰,例如SVN,CVS等耿战,最核心的區(qū)別蛋叼。
2、GIT把內(nèi)容按元數(shù)據(jù)方式存儲(chǔ),而SVN是按文件:所有的資源控制系統(tǒng)都是把文件的元信息隱藏在一個(gè)類似.svn,.cvs等的文件夾里狈涮。
3狐胎、GIT分支和SVN的分支不同:分支在SVN中一點(diǎn)不特別,就是版本庫中的另外的一個(gè)目錄歌馍。
4握巢、GIT沒有一個(gè)全局的版本號(hào),而SVN有:目前為止這是跟SVN相比GIT缺少的最大的一個(gè)特征骆姐。
5镜粤、GIT的內(nèi)容完整性要優(yōu)于SVN:GIT的內(nèi)容存儲(chǔ)使用的是SHA-1哈希算法。這能確保代碼內(nèi)容的完整性玻褪,確保在遇到磁盤故障和網(wǎng)絡(luò)問題時(shí)降低對(duì)版本庫的破壞肉渴。
1.2、Git 安裝配置
在使用Git前我們需要先安裝 Git带射。Git 目前支持 Linux/Unix同规、Solaris、Mac和 Windows 平臺(tái)上運(yùn)行窟社。
Git 各平臺(tái)安裝包下載地址為:http://git-scm.com/downloads
Windows 平臺(tái)上安裝
在 Windows 平臺(tái)上安裝 Git 同樣輕松券勺,有個(gè)叫做 msysGit 的項(xiàng)目提供了安裝包,可以到 GitHub 的頁面上下載 exe 安裝文件并運(yùn)行:
安裝包下載地址:http://msysgit.github.io/
Windows 上安裝 Git
完成安裝之后灿里,就可以使用命令行的 git 工具(已經(jīng)自帶了 ssh 客戶端)了舶沿,另外還有一個(gè)圖形界面的 Git 項(xiàng)目管理工具。
在開始菜單里找到"Git"->"Git Bash"锰瘸,會(huì)彈出 Git 命令窗口桌肴,你可以在該窗口進(jìn)行 Git 操作。
用戶信息
配置個(gè)人的用戶名稱和電子郵件地址:
$ git config --global user.name "runoob"
$ git config --global user.email test@runoob.com
如果用了 --global 選項(xiàng)色鸳,那么更改的配置文件就是位于你用戶主目錄下的那個(gè)社痛,以后你所有的項(xiàng)目都會(huì)默認(rèn)使用這里配置的用戶信息。
如果要在某個(gè)特定的項(xiàng)目中使用其他名字或者電郵命雀,只要去掉 --global 選項(xiàng)重新配置即可蒜哀,新的設(shè)定保存在當(dāng)前項(xiàng)目的 .git/config 文件里。
1.3吏砂、Git 基本原理
GIT有以下
工作區(qū):就是你在電腦里能看到的目錄撵儿。
暫存區(qū):英文叫stage, 或index。一般存放在 ".git目錄下" 下的index文件(.git/index)中狐血,所以我們把暫存區(qū)有時(shí)也叫作索引(index)统倒。
版本庫:工作區(qū)有一個(gè)隱藏目錄.git,這個(gè)不算工作區(qū)氛雪,而是Git的版本庫房匆。
圖中左側(cè)為工作區(qū),右側(cè)為版本庫。在版本庫中標(biāo)記為 "index" 的區(qū)域是暫存區(qū)(stage, index)浴鸿,標(biāo)記為 "master" 的是 master 分支所代表的目錄樹井氢。
圖中我們可以看出此時(shí) "HEAD" 實(shí)際是指向 master 分支的一個(gè)"游標(biāo)"。所以圖示的命令中出現(xiàn) HEAD 的地方可以用 master 來替換岳链。
圖中的 objects 標(biāo)識(shí)的區(qū)域?yàn)?Git 的對(duì)象庫花竞,實(shí)際位于 ".git/objects" 目錄下,里面包含了創(chuàng)建的各種對(duì)象及內(nèi)容掸哑。
當(dāng)對(duì)工作區(qū)修改(或新增)的文件執(zhí)行 "git add" 命令時(shí)约急,暫存區(qū)的目錄樹被更新,同時(shí)工作區(qū)修改(或新增)的文件內(nèi)容被寫入到對(duì)象庫中的一個(gè)新的對(duì)象中苗分,而該對(duì)象的ID被記錄在暫存區(qū)的文件索引中厌蔽。
當(dāng)執(zhí)行提交操作(git commit)時(shí),暫存區(qū)的目錄樹寫到版本庫(對(duì)象庫)中摔癣,master 分支會(huì)做相應(yīng)的更新奴饮。即 master 指向的目錄樹就是提交時(shí)暫存區(qū)的目錄樹。
當(dāng)執(zhí)行 "git reset HEAD" 命令時(shí)择浊,暫存區(qū)的目錄樹會(huì)被重寫戴卜,被 master 分支指向的目錄樹所替換,但是工作區(qū)不受影響琢岩。
當(dāng)執(zhí)行 "git rm --cached <file>" 命令時(shí)投剥,會(huì)直接從暫存區(qū)刪除文件,工作區(qū)則不做出改變担孔。
當(dāng)執(zhí)行 "git checkout ." 或者 "git checkout -- <file>" 命令時(shí)江锨,會(huì)用暫存區(qū)全部或指定的文件替換工作區(qū)的文件。這個(gè)操作很危險(xiǎn)攒磨,會(huì)清除工作區(qū)中未添加到暫存區(qū)的改動(dòng)。
當(dāng)執(zhí)行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時(shí)汤徽,會(huì)用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區(qū)和以及工作區(qū)中的文件娩缰。這個(gè)命令也是極具危險(xiǎn)性的,因?yàn)椴坏珪?huì)清除工作區(qū)中未提交的改動(dòng)谒府,也會(huì)清除暫存區(qū)中未提交的改動(dòng)拼坎。
2、Git 基本操作
2.1 完疫、創(chuàng)建新倉庫
創(chuàng)建新文件夾泰鸡,打開,然后執(zhí)行
git init
以創(chuàng)建新的 git 倉庫壳鹤。
2.2 盛龄、檢出倉庫
執(zhí)行如下命令以創(chuàng)建一個(gè)本地倉庫的克隆版本:
git clone /path/to/repository
如果是遠(yuǎn)端服務(wù)器上的倉庫,你的命令會(huì)是這個(gè)樣子:
git clone username@host:/path/to/repository
2.3 、添加和提交
你可以提出更改(把它們添加到暫存區(qū))余舶,使用如下命令:
git add <filename>
git add *
這是 git 基本工作流程的第一步啊鸭;使用如下命令以實(shí)際提交改動(dòng):
git commit -m "代碼提交信息"
現(xiàn)在,你的改動(dòng)已經(jīng)提交到了 HEAD匿值,但是還沒到你的遠(yuǎn)端倉庫
2.4 赠制、推送改動(dòng)
你的改動(dòng)現(xiàn)在已經(jīng)在本地倉庫的 HEAD 中了。執(zhí)行如下命令以將這些改動(dòng)提交到遠(yuǎn)端倉庫:
git push origin master
可以把 master 換成你想要推送的任何分支挟憔。
如果你還沒有克隆現(xiàn)有倉庫钟些,并欲將你的倉庫連接到某個(gè)遠(yuǎn)程服務(wù)器,你可以使用如下命令添加:
git remote add origin <server>
如此你就能夠?qū)⒛愕母膭?dòng)推送到所添加的服務(wù)器上去了绊谭。
2.5 政恍、分支
分支是用來將特性開發(fā)絕緣開來的。在你創(chuàng)建倉庫的時(shí)候龙誊,master 是“默認(rèn)的”分支抚垃。在其他分支上進(jìn)行開發(fā),完成后再將它們合并到主分支上趟大。
創(chuàng)建一個(gè)叫做“feature_x”的分支鹤树,并切換過去:
git checkout -b feature_x
切換回主分支:
git checkout master
再把新建的分支刪掉:
git branch -d feature_x
除非你將分支推送到遠(yuǎn)端倉庫,不然該分支就是 不為他人所見的:
git push origin <branch>
2.5 逊朽、分支
分支是用來將特性開發(fā)絕緣開來的罕伯。在你創(chuàng)建倉庫的時(shí)候,master 是“默認(rèn)的”分支叽讳。在其他分支上進(jìn)行開發(fā)追他,完成后再將它們合并到主分支上。
創(chuàng)建一個(gè)叫做“feature_x”的分支岛蚤,并切換過去:
git checkout -b feature_x
切換回主分支:
git checkout master
再把新建的分支刪掉:
git branch -d feature_x
除非你將分支推送到遠(yuǎn)端倉庫邑狸,不然該分支就是 不為他人所見的:
git push origin <branch>
2.6、分支更新與合并
要更新你的本地倉庫至最新改動(dòng)涤妒,執(zhí)行:
git pull
以在你的工作目錄中 獲鹊ノ怼(fetch) 并 合并(merge) 遠(yuǎn)端的改動(dòng)。
要合并其他分支到你的當(dāng)前分支(例如 master)她紫,執(zhí)行:
git merge <branch>
在這兩種情況下硅堆,git 都會(huì)嘗試去自動(dòng)合并改動(dòng)。遺憾的是贿讹,這可能并非每次都成功渐逃,并可能出現(xiàn)沖突(conflicts)。 這時(shí)候就需要你修改這些文件來手動(dòng)合并這些沖突(conflicts)民褂。改完之后茄菊,你需要執(zhí)行如下命令以將它們標(biāo)記為合并成功:
git add <filename>
在合并改動(dòng)之前疯潭,你可以使用如下命令預(yù)覽差異:
git diff <source_branch> <target_branch>
2.7、標(biāo)簽
通常我們在發(fā)布版本的時(shí)候會(huì)打上標(biāo)簽买羞。這個(gè)概念早已存在袁勺,在 SVN 中也有。你可以執(zhí)行如下命令創(chuàng)建一個(gè)叫做 1.0.0 的標(biāo)簽:
git tag 1.0.0 1b2e1d63ff
1b2e1d63ff 是你想要標(biāo)記的提交 ID 的前 10 位字符畜普∑诜幔可以使用下列命令獲取提交 ID:
git log
你也可以使用少一點(diǎn)的提交 ID 前幾位,只要它的指向具有唯一性吃挑。
2.8钝荡、替換本地改動(dòng)
假如你操作失誤(當(dāng)然,這最好永遠(yuǎn)不要發(fā)生)舶衬,你可以使用如下命令替換掉本地改動(dòng):
git checkout -- <filename>
此命令會(huì)使用 HEAD 中的最新內(nèi)容替換掉你的工作目錄中的文件埠通。已添加到暫存區(qū)的改動(dòng)以及新文件都不會(huì)受到影響。
假如你想丟棄你在本地的所有改動(dòng)與提交逛犹,可以到服務(wù)器上獲取最新的版本歷史端辱,并將你本地主分支指向它:
git fetch origin
git reset --hard origin/master
3、Git 權(quán)限控制介紹
3.1虽画、Git角色介紹
首先來了解下舞蔽,Git 中的五種角色:
角色 | 解釋 |
---|---|
Owner | Git 系統(tǒng)管理員 |
Master | Git 項(xiàng)目管理員 |
Developer | Git 項(xiàng)目開發(fā)人員 |
Reporter | Git 項(xiàng)目測試人員 |
Guest | 訪客 |
相關(guān)權(quán)限如下:
可以將特定branch,例如master码撰、develop等設(shè)為保護(hù)分支渗柿,由代碼管理員進(jìn)行維護(hù),合并開發(fā)人員提交的代碼脖岛。
4朵栖、Git 版本管理
4.1、建立項(xiàng)目
Git對(duì)于權(quán)限控制分為三種級(jí)別:私有柴梆、內(nèi)部陨溅、公開。
私有:項(xiàng)目訪問權(quán)限必須明確授權(quán)給每個(gè)用戶绍在,未授權(quán)的用戶無法訪問门扇。
內(nèi)部:該項(xiàng)目允許已登錄的用戶訪問。
公開:該項(xiàng)目允許任何人訪問揣苏。
為了保證代碼的安全性悯嗓,所有項(xiàng)目的建立均為私有件舵,同時(shí)在管理員面板中關(guān)閉內(nèi)部和公開項(xiàng)目的建立(Restricted visibility levels)卸察。
Git中支持將項(xiàng)目按照group進(jìn)行劃分,例如我們可以建立如下group:
車聯(lián)網(wǎng)(一級(jí)group)\項(xiàng)目A(二級(jí)group)
從而將不同的人員分配到不同的group級(jí)別铅祸,實(shí)現(xiàn)不同級(jí)別的權(quán)限配置坑质。
4.2合武、分支管理
GIT在技術(shù)層面上是一個(gè)無中心的分布式版本控制系統(tǒng),但在管理層面上涡扼,保持一個(gè)中心版本庫(Gitlab)稼跳。
一個(gè)中心版本庫(我們叫它origin)至少包括兩個(gè)分支,即“主分支(master)”和“開發(fā)分支(develop)”
團(tuán)隊(duì)成員從主分支(master)獲得的都是處于可發(fā)布狀態(tài)的代碼吃沪,而從開發(fā)分支(develop)應(yīng)該總能夠獲得最新開發(fā)進(jìn)展的代碼汤善。
在一個(gè)團(tuán)隊(duì)開發(fā)協(xié)作中有“輔助分支”的概念∑北耄“輔助分支”红淡,大體包括如下幾類:“管理功能開發(fā)”的分支、“幫助構(gòu)建可發(fā)布代碼”的分支降铸、“可以便捷的修復(fù)發(fā)布版本關(guān)鍵BUG”的分支在旱,等等⊥频В“輔助分支”的最大特點(diǎn)就是“生命周期十分有限”桶蝎,完成使命后即可被清除。
“輔助分支”分為三類谅畅,我們稱之為“Feature branches”登渣,“Release branches”,“Hotfix branches”铃彰。
下圖就是整個(gè)版本管理的生命周期:
4.2.1绍豁、 Feature branches
“Feature branches”,起源于develop分支牙捉,最終也會(huì)歸于develop分支竹揍。
“Feature branches”常用于開發(fā)一個(gè)獨(dú)立的新功能,且其最終的結(jié)局必然只有兩個(gè)邪铲,其一是合并入“develop”分支芬位,其二是被拋棄。最典型的“Fearture branches”一定是存在于團(tuán)隊(duì)開發(fā)者那里带到,而不應(yīng)該是“中心版本庫”中昧碉。
“Feature branches”起源于“develop”分支,實(shí)現(xiàn)方法是:
git checkout -b myfeature develop
“Feature branches”最終將在開發(fā)完成后合并到“develop”分支揽惹,實(shí)現(xiàn)方式是:
git checkout devleop
git merge --no-ff myfeature
(--no-ff被饿,即not fast forward,其作用是:要求git merge即使在fast forward條件下也要產(chǎn)生一個(gè)新的merge commit)
(此處搪搏,要求采用--no-ff的方式進(jìn)行分支合并狭握,其目的在于,希望保持原有“Feature branches”整個(gè)提交鏈的完整性)
git branch -d myfeature
git push origin develop
4.2.2疯溺、 Release branch
“Release branch”论颅,起源于develop分支哎垦,最終歸于“develop”或“master”分支。這類分支建議命名為“release-*”
“Relase branch”通常負(fù)責(zé)“短期的發(fā)布前準(zhǔn)備工作”恃疯、“小bug的修復(fù)工作”漏设、“版本號(hào)等元信息的準(zhǔn)備工作”。與此同時(shí)今妄,“develop”分支又可以承接下一個(gè)新功能的開發(fā)工作了郑口。
“Release branch”產(chǎn)生新提交的最好時(shí)機(jī)是“develop”分支已經(jīng)基本到達(dá)預(yù)期的狀態(tài),至少希望新功能已經(jīng)完全從“Feature branches”合并到“develop”分支了盾鳞。
創(chuàng)建“Release branches”潘酗,方法是:
git checkout -b release-1.2 develop
./bump-version.sh 1.2 (這個(gè)腳本用于將代碼所有涉及版本信息的地方都統(tǒng)一修改到1.2,另外雁仲,需要用戶根據(jù)自己的項(xiàng)目去編寫適合的bump-version.sh)
git commit -a -m "Bumped version number to 1.2"
在一段短時(shí)間內(nèi)仔夺,在“Release branches”上,我們可以繼續(xù)修復(fù)bug攒砖。在此階段缸兔,嚴(yán)禁新功能的并入,新功能應(yīng)該是被合并到“develop”分支的吹艇。
經(jīng)過若干bug修復(fù)后惰蜜,“Release branches”上的代碼已經(jīng)達(dá)到可發(fā)布狀態(tài),此時(shí)受神,需要完成三個(gè)動(dòng)作:第一是將“Release branches”合并到“master”分支抛猖,第二是一定要為master上的這個(gè)新提交打TAG(記錄里程碑),第三是要將“Release branches”合并回“develop”分支鼻听。
git checkout master
git merge --no-ff release-1.2
git tag -a 1.2 (使用-u/-s/-a參數(shù)會(huì)創(chuàng)建tag對(duì)象财著,而非軟tag)
git checkout develop
git merge --no-ff release-1.2
git branch -d release-1.2
4.2.3、 Hotfix branches
“Hotfix branches”源于“master”撑碴,歸于“develop”或“master”撑教,通常命名為“hotfix-*”
“Hotfix branches”類似于“Release branch”,但產(chǎn)生此分支總是非預(yù)期的關(guān)鍵BUG醉拓。
建議設(shè)立“Hotfix branches”的原因是:希望避免“develop分支”新功能的開發(fā)必須為BUG修復(fù)讓路的情況伟姐。
建立“Hotfix branches”,方法是:
git checkout -b hotfix-1.2.1 master
./bump-version.sh 1.2.1
git commit -a -m "Bumpt version to 1.2.1" (然后可以開始問題修復(fù)工作)
git commit -m "Fixed severe production problem" (在問題修復(fù)后亿卤,進(jìn)行第二次提交)
BUG修復(fù)后愤兵,需要將“Hotfix branches”合并回“master”分支,同時(shí)也需要合并回“develop”分支排吴,方法是:
git checkout master
git merge --no-ff hotfix-1.2.1
git tag -a 1.2.1
git checkout develop
git merge --no-ff hotfix-1.2.1
git branch -d hotfix-1.2.1
5秆乳、操作流程
角色 | 權(quán)限 | 解釋 |
---|---|---|
項(xiàng)目經(jīng)理 | Owner | 分支管理 |
開發(fā)人員 | Developer | feature、hotfix傍念、release代碼開發(fā) |
代碼管理員 | Master | 代碼merge |
測試人員 | Reporter | 測試 |
下面我們就在測試環(huán)境矫夷,進(jìn)行一次實(shí)戰(zhàn)演練。
如下是涉及到的角色和權(quán)限:
角色 | 權(quán)限 | 解釋 |
---|---|---|
項(xiàng)目經(jīng)理 | Owner | 分支管理 |
開發(fā)人員 | Developer | feature憋槐、hotfix双藕、release代碼開發(fā) |
代碼管理員 | Master | 代碼merge |
測試人員 | Reporter | 測試 |
首先項(xiàng)目經(jīng)理新建group和子group,接著在group下新建了一個(gè)項(xiàng)目project
由項(xiàng)目經(jīng)理 給開發(fā)人員分配權(quán)限阳仔。
為了測試我們通過控制臺(tái)忧陪,由項(xiàng)目經(jīng)理上傳一個(gè)文件方便創(chuàng)建分支。
可以看到近范,默認(rèn)會(huì)有一個(gè)master分支嘶摊。由項(xiàng)目經(jīng)理生成develop分支。
將這兩個(gè)分支設(shè)置為只能由項(xiàng)目經(jīng)理(或者由其他專人進(jìn)行评矩,后續(xù)稱為代碼管理員)merge叶堆。
然后項(xiàng)目經(jīng)理生成兩個(gè)新分支feature1,feature2斥杜,由兩個(gè)開發(fā)人員進(jìn)行開發(fā)虱颗。
兩個(gè)開發(fā)人員各自對(duì)自己的feature進(jìn)行修改后,提交merge request蔗喂。
由代碼管理員進(jìn)行兩個(gè)feature源碼merge忘渔,如果有沖突代碼,需要進(jìn)行沖突解決之后才能merge成功缰儿。
feature均開發(fā)完成之后項(xiàng)目經(jīng)理從develop中拉出release進(jìn)行測試畦粮。測試過程中release分支如果有bug產(chǎn)生,開發(fā)人員進(jìn)行修復(fù)之后乖阵,代碼管理員將修改的代碼merge回develop宣赔。
release版本在測試完畢后,代碼管理員將release代碼merge到master,同時(shí)打上tag1.0瞪浸。
tag1.0可用來進(jìn)行生產(chǎn)發(fā)布拉背。如果生產(chǎn)版本有問題,從對(duì)應(yīng)版本的tag上拉出hotfix分支進(jìn)行修復(fù)之后在hotfix分支上進(jìn)行測試默终,完畢之后merge回develop和master椅棺。
6、配置SSH免密登陸
為了防止所有人或者是登陸用戶能獲取到源碼齐蔽,目前的項(xiàng)目都設(shè)置為private两疚,這樣只有經(jīng)過授權(quán)的用戶(項(xiàng)目小組成員)才能clone代碼,下面介紹如何使用ssh進(jìn)行免密登陸含滴。
6.1 诱渤、生成免密文件
確保本機(jī)已經(jīng)安裝了Git,右鍵鼠標(biāo)谈况,選中 “Git Bash here”勺美,當(dāng)然你也可以在windows的 “開始”--->“所以程序”递胧,或者安裝目錄、快速搜索打開它赡茸。
windows下需要在用戶目錄下創(chuàng)建.ssh文件夾缎脾, mkdir .ssh。
cd .ssh
git config --global user.name "name"
git config --global user.email "email"
ssh-keygen -t rsa -C "username"
username是git賬號(hào)占卧,同時(shí)設(shè)置全局名字和郵箱遗菠。
連續(xù)三次回車之后,在.ssh文件夾下會(huì)生成ssh秘鑰文件华蜒。
最后得到了兩個(gè)文件:id_rsa和id_rsa.pub
打開id_rsa.pub辙纬,復(fù)制里面的文字。
6.2 叭喜、git網(wǎng)站上配置秘鑰
選擇個(gè)人設(shè)置贺拣。
點(diǎn)擊add key,即可設(shè)置成功捂蕴。
6.3 纵柿、測試
ssh git@gitlab.com
將gitlab.com替換成你所用git的host。
看到welcome to gitlab等字樣就顯示成功了启绰。
參考資料:
GIT分支管理是一門藝術(shù) http://roclinux.cn/?p=2129#comments
Git 教程 http://www.runoob.com/git/git-tutorial.html