afrag |
|
|||
記錄學(xué)習(xí)和成長(zhǎng)的歷程 |
日歷
統(tǒng)計(jì)
導(dǎo)航常用鏈接留言簿隨筆分類隨筆檔案文章檔案搜索積分與排名
最新評(píng)論
閱讀排行榜評(píng)論排行榜 |
轉(zhuǎn)發(fā)自 道法術(shù)器的博客文章——Git教程Git是一個(gè)分布式的版本控制系統(tǒng)。 注意上面的”分布式的“這個(gè)限定詞,這一點(diǎn)是Git和CVS,VSN等其他版本控制系統(tǒng)最大的分別。 集中式版本控制系統(tǒng)最大的毛病就是必須聯(lián)網(wǎng)才能夠工作,也就是各個(gè)客戶端必須連接到中央倉(cāng)庫(kù)才能夠工作。 分布式的版本控制系統(tǒng)中,不必有中央倉(cāng)庫(kù),每個(gè)人的電腦上都有一個(gè)完整的版本庫(kù)。我們可以在自己的電腦上修改、提交。如果兩個(gè)人需要交換修改的代碼,則需要將自己的修改推送給對(duì)方。 這個(gè)教程的主要目的是讓大家了解使用Git進(jìn)行版本管理的一些基本操作和邏輯,讓大家對(duì)Git的使用有一個(gè)基本的了解。如果想要詳細(xì)了解每個(gè)命令的用法,或者要了解一些“高級(jí)”的命令,建議大家還是去看看Git的手冊(cè)。 2. 創(chuàng)建本地倉(cāng)庫(kù)關(guān)于Git的安裝,這里就不講了,網(wǎng)上有很多文章,大家根據(jù)自己的系統(tǒng),找一篇文章照著做就可以了。這里主要講解Git的一些概念和操作。 前面已經(jīng)說(shuō)過(guò),Git是一個(gè)分布式的版本控制系統(tǒng),每個(gè)人的電腦上都有一個(gè)完整的版本庫(kù),我們把這個(gè)版本庫(kù)稱為本地倉(cāng)庫(kù)。所有其他的倉(cāng)庫(kù),無(wú)論是同事電腦上的,還是中央服務(wù)器的,我們都稱為遠(yuǎn)程倉(cāng)庫(kù)。 創(chuàng)建本地倉(cāng)庫(kù)有兩種方式,第一種是我們從零開(kāi)始創(chuàng)建,第二種是從遠(yuǎn)程倉(cāng)庫(kù)克隆一份。 我們可以把版本倉(cāng)庫(kù)理解為一個(gè)目錄,其中保存了我們所有讓git管理的文件。Git能夠跟蹤這些文件的修改、刪除,能夠追蹤這些文件的歷史,并且可以還原。 2.1 從頭開(kāi)始創(chuàng)建本地倉(cāng)庫(kù)從頭開(kāi)始創(chuàng)建本地倉(cāng)庫(kù)非常簡(jiǎn)單。
2.2 從遠(yuǎn)程倉(cāng)庫(kù)克隆相比從頭開(kāi)始創(chuàng)建本地倉(cāng)庫(kù),我們做得更多的是從遠(yuǎn)程倉(cāng)庫(kù)克隆一份。理論上來(lái)說(shuō)遠(yuǎn)程倉(cāng)庫(kù)可以是任何一臺(tái)電腦上的倉(cāng)庫(kù),但是通常來(lái)說(shuō),我們會(huì)在github,或自己搭建的git服務(wù)器上創(chuàng)建中央倉(cāng)庫(kù),團(tuán)隊(duì)中的所有成員都從該倉(cāng)庫(kù)上克隆,并在后續(xù)將自己的修改上傳上去,或者從中央倉(cāng)庫(kù)讀取其他同事的修改。因此我們這樣只講怎樣中央倉(cāng)庫(kù)克隆到本地倉(cāng)庫(kù)。
上面的命令中,版本庫(kù)的網(wǎng)址中是可以帶上協(xié)議、用戶名等信息的。Git支持http(s),ssh,git,ftp(s),本地文件協(xié)議等不同的協(xié)議。 3 使用本地倉(cāng)庫(kù)進(jìn)行版本管理3.1 工作區(qū)和暫存區(qū)為了能夠更好的使用本地倉(cāng)庫(kù)進(jìn)行版本管理,我們先了解一下工作區(qū)和暫存區(qū)的概念。 無(wú)論我們是從遠(yuǎn)程倉(cāng)庫(kù)克隆,還是使用 本地倉(cāng)庫(kù)目錄是我們的工作區(qū),我們要管理的文件都在這個(gè)目錄中。但是 在這個(gè)版本庫(kù)中,保存了很多的東西,其中最重要的是暫存區(qū),以及分支。關(guān)于分支的概念,我們以后再解釋。目前來(lái)說(shuō),我們也只有一個(gè)分支,也就是Git自動(dòng)為我們創(chuàng)建的master分區(qū)。還有一個(gè)指向master分區(qū)的指針,叫做HEAD。 前面我們已經(jīng)提到過(guò),在添加一個(gè)文件到Git本地倉(cāng)庫(kù)中的時(shí)候,需要先執(zhí)行 所以,我們其實(shí)可以執(zhí)行多次 可以使用git status來(lái)查看有哪些修改沒(méi)有add到暫存區(qū),有哪些修改在暫存區(qū)中,沒(méi)有提交到版本庫(kù)。 3.2 提交版本和查看歷史我們修改了一個(gè)或多個(gè)文件之后,可以使用
這個(gè)命令返回的信息中,包含了提交的分支,本次提交自動(dòng)生成的版本號(hào)(commit id),輸入的備注,以及修改內(nèi)容的統(tǒng)計(jì)信息。 注意這里的版本號(hào)可能不是完整的版本號(hào),而只是版本號(hào)的前幾位。 我們可以看到,Git的版本號(hào)是一個(gè)用十六進(jìn)制表示的隨機(jī)數(shù)字,這是為了避免各自在本地?cái)?shù)據(jù)庫(kù)中提交時(shí)版本號(hào)的沖突。 Git會(huì)記錄下我們所有的版本歷史,可以使用 3.3 版本回退版本回退是版本管理系統(tǒng)最基本的功能。如果不能回退,要這系統(tǒng)何用。 要回退,首先需要知道回退到哪個(gè)版本。可以使用 使用 這下就體現(xiàn)了提交的時(shí)候使用備注的好處了,我們可以通過(guò)備注知道每一次修改的原因和內(nèi)容,這樣才知道需要回退到哪個(gè)版本。 如果我們從今天的版本回退到了昨天的版本,還能不能回到今天的版本呢?可以的,但是前提要是你還記得今天的版本的版本號(hào)。如果我們前面的窗口沒(méi)有關(guān)閉,可以從 3.4 管理修改前面講過(guò)了工作區(qū)和暫存區(qū)。因此Git相比其他的版本管理系統(tǒng)多了一層。這一層有什么作用呢? 我們?cè)谔峤坏臅r(shí)候,提交的是暫存區(qū)中的內(nèi)容,而不是工作區(qū)中的內(nèi)容。因此,我們?cè)谛薷牡臅r(shí)候,可以多次將中間代碼添加到暫存區(qū)。我們既不需要產(chǎn)生大量的中間版本號(hào)和提交記錄,也可以保證不會(huì)因?yàn)楹罄m(xù)的修改弄丟了前面的代碼。我們可以大膽的試錯(cuò),發(fā)現(xiàn)不合適了,很容易回滾到前一個(gè)版本。 我們可以使用 當(dāng)然,刪除文件也是一種修改。一般我們把文件從Git的目錄中刪除之后,Git會(huì)檢測(cè)到,并且使用 如果是誤刪除的,可以使用 4 分支管理前面我們提到了,從 分支允許我們創(chuàng)建另外一條”路徑“,同時(shí)管理兩個(gè)版本的代碼。例如,我們完成了1.0版本,進(jìn)入2.0版本的開(kāi)發(fā)。但是我們同時(shí)需要進(jìn)行1.0版本的維護(hù),修復(fù)bug。這個(gè)時(shí)候,我們就可以同時(shí)維護(hù)1.0分支和2.0分支。 4.1 創(chuàng)建與合并分支分支就是提交記錄組成的一個(gè)時(shí)間線,因此一個(gè)分支可以表示如下: 分支master指向該分支中的最后一次提交。然后Git還會(huì)用HEAD指向master,表明當(dāng)前的分支是master分支。每次提交,master都會(huì)向前移動(dòng)一步,一直指向最新的提交,master分支的時(shí)間線也越來(lái)越長(zhǎng)。 如果我們需要?jiǎng)?chuàng)建一個(gè)新的分支,例如從當(dāng)前最新提交創(chuàng)建一個(gè)dev分支,那么其實(shí)只是創(chuàng)建了一個(gè)名為dev的指針,指向最新的提交,同時(shí)將HEAD修改為指向dev。使用的命令是 因此,在Git中創(chuàng)建分支非常的快,因?yàn)橹皇莿?chuàng)建一個(gè)指針,然后修改做一個(gè)指針。 從現(xiàn)在開(kāi)始,所有的提交操作都是針對(duì)dev分支了,因此,如果做了一次新的提交,dev會(huì)向前移動(dòng)一步,但是master指針不變,如下圖: 這個(gè)時(shí)候,要合并分支也很容易,只需要先使用 當(dāng)一個(gè)分支完成了歷史使命的時(shí)候,我們可以將其刪除。例如,如果我們要?jiǎng)h除dev分支,只需要執(zhí)行 4.2 解決分支之間的沖突前面介紹的合并分支是最簡(jiǎn)單的一種情況,當(dāng)然現(xiàn)實(shí)世界通常不會(huì)這么簡(jiǎn)單。現(xiàn)實(shí)中常見(jiàn)的情況時(shí)在兩個(gè)分支上我們都有提交,如下圖所示: 這個(gè)時(shí)候,如果我們執(zhí)行 如果我們打開(kāi)沖突的文件,會(huì)看到類似下面的內(nèi)容:
對(duì)于每一個(gè)沖突,Git中會(huì)用 5 通過(guò)遠(yuǎn)程倉(cāng)庫(kù)合作一個(gè)團(tuán)隊(duì)中有多個(gè)開(kāi)發(fā)人員,他們一起協(xié)助來(lái)完成軟件開(kāi)發(fā)的工作。因此,不可能大家都只在自己的本地倉(cāng)庫(kù)中修修改改。通常來(lái)說(shuō),我們會(huì)配置一個(gè)”中央倉(cāng)庫(kù)“,大家都把自己的本地倉(cāng)庫(kù)中的代碼要提交到中央倉(cāng)庫(kù)。 5.1 日常的工作流程在軟件開(kāi)發(fā)過(guò)程中,我們首先是從中央倉(cāng)庫(kù)下載代碼到本地倉(cāng)庫(kù),這個(gè)操作在前面的第2.2節(jié)中已經(jīng)描述過(guò)了。 有了本地倉(cāng)庫(kù)之后,日常的工作流程通常上:
5.2 從中央倉(cāng)庫(kù)拉取代碼從中央倉(cāng)庫(kù)拉取代碼,使用的是 還有一種情況,是從中央倉(cāng)庫(kù)抓取一個(gè)新的分支。我們使用 如果要從中央倉(cāng)庫(kù)獲取一個(gè)新的分支,比如dev分支,則需要先執(zhí)行 5.3 推送分支到中央倉(cāng)庫(kù)我們?cè)诒镜刈龅男薷模枰蟼鞯街醒雮}(cāng)庫(kù),使用的是 如果從上次下載代碼到本次推送之間,遠(yuǎn)程倉(cāng)庫(kù)上的代碼沒(méi)有變化,那么本次推送就沒(méi)有問(wèn)題。但是通常來(lái)說(shuō),在團(tuán)隊(duì)合作的時(shí)候,在這段時(shí)間內(nèi)會(huì)有其他人推送了新的代碼到中央倉(cāng)庫(kù)。這個(gè)時(shí)候使用 6 其他6.1 標(biāo)簽管理在Git中,每一次提交都有一個(gè)版本號(hào),但是這個(gè)版本號(hào)對(duì)人類很不友好。沒(méi)有任何含義,并且又長(zhǎng)又難記。我們?cè)谌粘5慕涣髦袩o(wú)法使用這個(gè)版本號(hào)。 這種情況下,引入了tag的功能。Tag就是一個(gè)標(biāo)簽,我們可以在重要的提交版本上添加一個(gè)tag,這個(gè)tag其實(shí)就是指向這一次提交的版本。我們可以給tag賦予有意義的名稱,例如V1.0這樣的,這樣方便我們?nèi)粘5慕涣鳎蛯?lái)的查找。 在Git中打標(biāo)簽非常簡(jiǎn)單,執(zhí)行 執(zhí)行上面的命令的時(shí)候,默認(rèn)是將標(biāo)簽打在分支的最后一次提交上。如果要將標(biāo)簽打在其他的提交上,可以使用 可以使用 我們創(chuàng)建的標(biāo)簽都是在本地,如果需要將標(biāo)簽推送到遠(yuǎn)程倉(cāng)庫(kù),則可以使用 標(biāo)簽是不能移動(dòng)和修改的,但是可以刪除。因此,如果標(biāo)簽打錯(cuò)了,修改的方式就是刪除錯(cuò)誤的標(biāo)簽,重新創(chuàng)建正確的標(biāo)簽。 如果標(biāo)簽已經(jīng)被推送到了遠(yuǎn)程倉(cāng)庫(kù),則需要先刪除本地標(biāo)簽,然后使用如下形式的push命令來(lái)刪除遠(yuǎn)程倉(cāng)庫(kù)中的標(biāo)簽。
6.2 git stash操作有些時(shí)候,我們?cè)诠ぷ鞯闹型荆瑫?huì)接到一些緊急的任務(wù),比如生產(chǎn)環(huán)境的bug修復(fù)。這個(gè)時(shí)候我們手頭的工作才做了一半,既不能提交,也不能丟棄。但是我們又需要切換到另外的分支中來(lái)處理緊急任務(wù),該怎么辦? git stash命令會(huì)將工作區(qū)的修改“隱藏”起來(lái)。如下例所示:
這個(gè)命令會(huì)將工作區(qū)中的修改創(chuàng)建一個(gè)存根,并保存到堆棧中。我們可以使用 當(dāng)緊急任務(wù)完成之后,我們?cè)谇袚Q回原來(lái)的分支,這個(gè)時(shí)候可以使用 6.3 git配置
|
![]() |
|
Copyright © afrag | Powered by: 博客園 模板提供:滬江博客 |