《LINUX學(xué)習(xí):Git部署與常用基本命令詳解》要點(diǎn):
本文介紹了LINUX學(xué)習(xí):Git部署與常用基本命令詳解,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
GIT(分布式版本控制系統(tǒng))
關(guān)于版本控制
什么是“版本控制”?我為什么要關(guān)心它呢?版本控制是一種記錄一個(gè)或若干文件內(nèi)容變化,以便將來(lái)查閱特定版本修訂情況的系統(tǒng).在本書(shū)所展示的例子中,我們對(duì)保存著軟件源代碼的文件作版本控制,但實(shí)際上,你可以對(duì)任何類(lèi)型的文件進(jìn)行版本控制.
如果你是位圖形或網(wǎng)頁(yè)設(shè)計(jì)師,可能會(huì)需要保存某一幅圖片或頁(yè)面布局文件的所有修訂版本(這或許是你非??释麚碛械墓δ?,采用版本控制系統(tǒng)(VCS)是個(gè)明智的選擇.有了它你就可以將某個(gè)文件回溯到之前的狀態(tài),甚至將整個(gè)項(xiàng)目都回退到過(guò)去某個(gè)時(shí)間點(diǎn)的狀態(tài),你可以比較文件的變化細(xì)節(jié),查出最后是誰(shuí)修改了哪個(gè)地方,從而找出導(dǎo)致怪異問(wèn)題出現(xiàn)的原因,又是誰(shuí)在何時(shí)報(bào)告了某個(gè)功能缺陷等等.使用版本控制系統(tǒng)通常還意味著,就算你亂來(lái)一氣把整個(gè)項(xiàng)目中的文件改的改刪的刪,你也照樣可以輕松恢復(fù)到原先的樣子.但額外增加的工作量卻微乎其微.
本地版本控制系統(tǒng)
許多人習(xí)慣用復(fù)制整個(gè)項(xiàng)目目錄的方式來(lái)保存不同的版本,或許還會(huì)改名加上備份時(shí)間以示區(qū)別.這么做唯一的好處就是簡(jiǎn)單.不過(guò)壞處也不少:有時(shí)候會(huì)混淆所在的工作目錄,一旦弄錯(cuò)文件丟了數(shù)據(jù)就沒(méi)法撤銷(xiāo)恢復(fù).
為了解決這個(gè)問(wèn)題,人們很久以前就開(kāi)發(fā)了許多種本地版本控制系統(tǒng),大多都是采用某種簡(jiǎn)單的數(shù)據(jù)庫(kù)來(lái)記錄文件的歷次更新差異.
本地版本控制圖解
其中最流行的一種叫做 rcs,現(xiàn)今許多計(jì)算機(jī)系統(tǒng)上都還看得到它的蹤影.甚至在流行的 Mac OS X 系統(tǒng)上安裝了開(kāi)發(fā)者工具包之后,也可以使用 rcs 命令.它的工作原理基本上就是保存并管理文件補(bǔ)丁(patch).文件補(bǔ)丁是一種特定格式的文本文件,記錄著對(duì)應(yīng)文件修訂前后的內(nèi)容變化.所以,根據(jù)每次 修訂后的補(bǔ)丁,rcs 可以通過(guò)不斷打補(bǔ)丁,計(jì)算出各個(gè)版本的文件內(nèi)容.
集中化的版本控制系統(tǒng)
接下來(lái)人們又遇到一個(gè)問(wèn)題,如何讓在不同系統(tǒng)上的開(kāi)發(fā)者協(xié)同工作?于是,集中化的版本控制系統(tǒng)( Centralized Version Control Systems,簡(jiǎn)稱 CVCS )應(yīng)運(yùn)而生.這類(lèi)系統(tǒng),諸如 CVS,Subversion 以及 Perforce 等,都有一個(gè)單一的集中管理的服務(wù)器,保存所有文件的修訂版本,而協(xié)同工作的人們都通過(guò)客戶端連到這臺(tái)服務(wù)器,取出最新的文件或者提交更新.多年以來(lái),這 已成為版本控制系統(tǒng)的標(biāo)準(zhǔn)做法.
集中化的版本控制圖解
這種做法帶來(lái)了許多好處,特別是相較于老式的本地 VCS 來(lái)說(shuō).現(xiàn)在,每個(gè)人都可以在一定程度上看到項(xiàng)目中的其他人正在做些什么.而管理員也可以輕松掌控每個(gè)開(kāi)發(fā)者的權(quán)限,并且管理一個(gè) CVCS 要遠(yuǎn)比在各個(gè)客戶端上維護(hù)本地?cái)?shù)據(jù)庫(kù)來(lái)得輕松容易.
事分兩面,有好有壞.這么做最顯而易見(jiàn)的缺點(diǎn)是中央服務(wù)器的單點(diǎn)故障.如果宕機(jī)一小時(shí),那么在這一小時(shí)內(nèi),誰(shuí)都無(wú)法提交更新,也就無(wú)法協(xié)同工作.要 是中央服務(wù)器的磁盤(pán)發(fā)生故障,碰巧沒(méi)做備份,或者備份不夠及時(shí),就還是會(huì)有丟失數(shù)據(jù)的風(fēng)險(xiǎn).最壞的情況是徹底丟失整個(gè)項(xiàng)目的所有歷史更改記錄,而被客戶端 提取出來(lái)的某些快照數(shù)據(jù)除外,但這樣的話依然是個(gè)問(wèn)題,你不能保證所有的數(shù)據(jù)都已經(jīng)有人事先完整提取出來(lái)過(guò).本地版本控制系統(tǒng)也存在類(lèi)似問(wèn)題,只要整個(gè)項(xiàng) 目的歷史記錄被保存在單一位置,就有丟失所有歷史更新記錄的風(fēng)險(xiǎn).
分布式版本控制系統(tǒng)
于是分布式版本控制系統(tǒng)( Distributed Version Control System,簡(jiǎn)稱 DVCS )面世了.在這類(lèi)系統(tǒng)中,像 Git,Mercurial,Bazaar 以及 Darcs 等,客戶端并不只提取最新版本的文件快照,而是把原始的代碼倉(cāng)庫(kù)完整地鏡像下來(lái).這么一來(lái),任何一處協(xié)同工作用的服務(wù)器發(fā)生故障,事后都可以用任何一個(gè)鏡 像出來(lái)的本地倉(cāng)庫(kù)恢復(fù).因?yàn)槊恳淮蔚奶崛〔僮?實(shí)際上都是一次對(duì)代碼倉(cāng)庫(kù)的完整備份
分布式版本控制圖解
更進(jìn)一步,許多這類(lèi)系統(tǒng)都可以指定和若干不同的遠(yuǎn)端代碼倉(cāng)庫(kù)進(jìn)行交互.籍此,你就可以在同一個(gè)項(xiàng)目中,分別和不同工作小組的人相互協(xié)作.你可以根據(jù)需要設(shè)定不同的協(xié)作流程,比如層次模型式的工作流,而這在以前的集中式系統(tǒng)中是無(wú)法實(shí)現(xiàn)的.
Git 簡(jiǎn)史
同生活中的許多偉大事物一樣,Git 誕生于一個(gè)極富紛爭(zhēng)大舉創(chuàng)新的年代.
Git --- The stupid content tracker, 傻瓜內(nèi)容跟蹤器.Linus Torvalds 是這樣給我們介紹 Git 的.
Git 是用于 Linux內(nèi)核開(kāi)發(fā)的版本控制工具.與常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本庫(kù)的方式,不必服務(wù)器端軟件支持(wingeddevil注:這得分是用什么樣的服務(wù)端,使用http協(xié)議或者git協(xié)議等不太一樣.并且在push和pull的時(shí)候和服務(wù)器端還是有交互的.),使源代碼的發(fā)布和交流極其方便. Git 的速度很快,這對(duì)于諸如 Linux kernel 這樣的大項(xiàng)目來(lái)說(shuō)自然很重要. Git 最為出色的是它的合并跟蹤(merge tracing)能力.
實(shí)際上內(nèi)核開(kāi)發(fā)團(tuán)隊(duì)決定開(kāi)始開(kāi)發(fā)和使用 Git 來(lái)作為內(nèi)核開(kāi)發(fā)的版本控制系統(tǒng)的時(shí)候,世界開(kāi)源社群的反對(duì)聲音不少,最大的理由是 Git 太艱澀難懂,從 Git 的內(nèi)部工作機(jī)制來(lái)說(shuō),的確是這樣.但是隨著開(kāi)發(fā)的深入,Git 的正常使用都由一些友好的腳本命令來(lái)執(zhí)行,使 Git 變得非常好用,即使是用來(lái)管理我們自己的開(kāi)發(fā)項(xiàng)目,Git 都是一個(gè)友好,有力的工具.現(xiàn)在,越來(lái)越多的著名項(xiàng)目采用 Git 來(lái)管理項(xiàng)目開(kāi)發(fā).
作為開(kāi)源自由原教旨主義項(xiàng)目,Git 沒(méi)有對(duì)版本庫(kù)的瀏覽和修改做任何的權(quán)限限制.
Linux 內(nèi)核開(kāi)源項(xiàng)目有著為數(shù)眾廣的參與者.絕大多數(shù)的 Linux 內(nèi)核維護(hù)工作都花在了提交補(bǔ)丁和保存歸檔的繁瑣事務(wù)上(1991-2002年間).到 2002 年,整個(gè)項(xiàng)目組開(kāi)始啟用一個(gè)專有的分布式版本控制系統(tǒng) BitKeeper 來(lái)管理和維護(hù)代碼.
到了 2005 年,開(kāi)發(fā) BitKeeper 的商業(yè)公司同 Linux 內(nèi)核開(kāi)源社區(qū)的合作關(guān)系結(jié)束,他們收回了 Linux 內(nèi)核社區(qū)免費(fèi)使用 BitKeeper 的權(quán)力.這就迫使 Linux 開(kāi)源社區(qū)(特別是 Linux 的締造者 Linux Torvalds)基于使用 BitKcheper 時(shí)的經(jīng)驗(yàn)教訓(xùn),開(kāi)發(fā)出自己的版本系統(tǒng).他們對(duì)新的系統(tǒng)制訂了若干目標(biāo):
速度
簡(jiǎn)單的設(shè)計(jì)
對(duì)非線性開(kāi)發(fā)模式的強(qiáng)力支持(允許成千上萬(wàn)個(gè)并行開(kāi)發(fā)的分支)
完全分布式
有能力高效管理類(lèi)似 Linux 內(nèi)核一樣的超大規(guī)模項(xiàng)目(速度和數(shù)據(jù)量)
自誕生于 2005 年以來(lái),Git 日臻成熟完善,在高度易用的同時(shí),仍然保留著初期設(shè)定的目標(biāo).它的速度飛快,極其適合管理大項(xiàng)目,有著令人難以置信的非線性分支管理系統(tǒng)(參見(jiàn) Git 分支).
起步 - Git 基礎(chǔ)
Git 基礎(chǔ)
那么,簡(jiǎn)單地說(shuō),Git 究竟是怎樣的一個(gè)系統(tǒng)呢?請(qǐng)注意接下來(lái)的內(nèi)容非常重要,若你理解了 Git 的思想和基本工作原理,用起來(lái)就會(huì)知其所以然,游刃有余.在開(kāi)始學(xué)習(xí) Git 的時(shí)候,請(qǐng)努力分清你對(duì)其它版本管理系統(tǒng)的已有認(rèn)識(shí),如 Subversion 和 Perforce 等;這么做能幫助你使用工具時(shí)避免發(fā)生混淆. Git 在保存和對(duì)待各種信息的時(shí)候與其它版本控制系統(tǒng)有很大差異,盡管操作起來(lái)的命令形式非常相近,理解這些差異將有助于防止你使用中的困惑.
直接記錄快照,而非差異比較
Git 和其它版本控制系統(tǒng)(包括 Subversion 和近似工具)的主要差別在于 Git 對(duì)待數(shù)據(jù)的方法.概念上來(lái)區(qū)分,其它大部分系統(tǒng)以文件變更列表的方式存儲(chǔ)信息.這類(lèi)系統(tǒng)(CVS、Subversion、Perforce、Bazaar 等等)將它們保存的信息看作是一組基本文件和每個(gè)文件隨時(shí)間逐步累積的差異.
存儲(chǔ)每個(gè)文件與初始版本的差異.
Git 不按照以上方式對(duì)待或保存數(shù)據(jù).反之,Git 更像是把數(shù)據(jù)看作是對(duì)小型文件系統(tǒng)的一組快照.每次你提交更新,或在 Git 中保存項(xiàng)目狀態(tài)時(shí),它主要對(duì)當(dāng)時(shí)的全部文件制作一個(gè)快照并保存這個(gè)快照的索引.為了高效,如果文件沒(méi)有修改,Git 不再重新存儲(chǔ)該文件,而是只保留一個(gè)鏈接指向之前存儲(chǔ)的文件. Git 對(duì)待數(shù)據(jù)更像是一個(gè) 快照流.
Git 存儲(chǔ)項(xiàng)目隨時(shí)間改變的快照.
這是 Git 與幾乎所有其它版本控制系統(tǒng)的重要區(qū)別.因此 Git 重新考慮了以前每一代版本控制系統(tǒng)延續(xù)下來(lái)的諸多方面. Git 更像是一個(gè)小型的文件系統(tǒng),提供了許多以此為基礎(chǔ)構(gòu)建的超強(qiáng)工具,而不只是一個(gè)簡(jiǎn)單的 VCS.稍后我們?cè)贕it 分支討論 Git 分支管理時(shí),將探究這種方式對(duì)待數(shù)據(jù)所能獲得的益處.
更多詳情見(jiàn)請(qǐng)繼續(xù)閱讀下一頁(yè)的精彩內(nèi)容:
_baidu_page_break_tag_近乎所有操作都是本地執(zhí)行
在 Git 中的絕大多數(shù)操作都只需要訪問(wèn)本地文件和資源,一般不需要來(lái)自網(wǎng)絡(luò)上其它計(jì)算機(jī)的信息.如果你習(xí)慣于所有操作都有網(wǎng)絡(luò)延時(shí)開(kāi)銷(xiāo)的集中式版本控制系統(tǒng),Git 在這方面會(huì)讓你感到速度之神賜給了 Git 超凡的能量.因?yàn)槟阍诒镜卮疟P(pán)上就有項(xiàng)目的完整歷史,所以大部分操作看起來(lái)瞬間完成.
舉個(gè)例子,要瀏覽項(xiàng)目的歷史,Git 不需外連到服務(wù)器去獲取歷史,然后再顯示出來(lái)——它只需直接從本地?cái)?shù)據(jù)庫(kù)中讀取.你能立即看到項(xiàng)目歷史.如果你想查看當(dāng)前版本與一個(gè)月前的版本之間引入的修改,Git 會(huì)查找到一個(gè)月前的文件做一次本地的差異計(jì)算,而不是由遠(yuǎn)程服務(wù)器處理或從遠(yuǎn)程服務(wù)器拉回舊版本文件再來(lái)本地處理.
這也意味著你離線或者沒(méi)有 VPN 時(shí),幾乎可以進(jìn)行任何操作.如你在飛機(jī)或火車(chē)上想做些工作,你能愉快地提交,直到有網(wǎng)絡(luò)連接時(shí)再上傳.如你回家后 VPN 客戶端不正常,你仍能工作.使用其它系統(tǒng),做到如此是不可能或很費(fèi)力的.比如,用 Perforce,你沒(méi)有連接服務(wù)器時(shí)幾乎不能做什么事;用 Subversion 和 CVS,你能修改文件,但不能向數(shù)據(jù)庫(kù)提交修改(因?yàn)槟愕谋镜財(cái)?shù)據(jù)庫(kù)離線了).這看起來(lái)不是大問(wèn)題,但是你可能會(huì)驚喜地發(fā)現(xiàn)它帶來(lái)的巨大的不同.
Git 保證完整性
Git 中所有數(shù)據(jù)在存儲(chǔ)前都計(jì)算校驗(yàn)和,然后以校驗(yàn)和來(lái)引用.這意味著不可能在 Git 不知情時(shí)更改任何文件內(nèi)容或目錄內(nèi)容.這個(gè)功能建構(gòu)在 Git 底層,是構(gòu)成 Git 哲學(xué)不可或缺的部分.若你在傳送過(guò)程中丟失信息或損壞文件,Git 就能發(fā)現(xiàn).
Git 用以計(jì)算校驗(yàn)和的機(jī)制叫做 SHA-1 散列(hash,哈希).這是一個(gè)由 40 個(gè)十六進(jìn)制字符(0-9 和 a-f)組成字符串,基于 Git 中文件的內(nèi)容或目錄結(jié)構(gòu)計(jì)算出來(lái). SHA-1 哈??雌饋?lái)是這樣:
24b9da6552252987aa493b52f8696cd6d3b00373
Git 中使用這種哈希值的情況很多,你將經(jīng)常看到這種哈希值.實(shí)際上,Git 數(shù)據(jù)庫(kù)中保存的信息都是以文件內(nèi)容的哈希值來(lái)索引,而不是文件名.
Git 一般只添加數(shù)據(jù)
你執(zhí)行的 Git 操作,幾乎只往 Git 數(shù)據(jù)庫(kù)中增加數(shù)據(jù).很難讓 Git 執(zhí)行任何不可逆操作,或者讓它以任何方式清除數(shù)據(jù).同別的 VCS 一樣,未提交更新時(shí)有可能丟失或弄亂修改的內(nèi)容;但是一旦你提交快照到 Git 中,就難以再丟失數(shù)據(jù),特別是如果你定期的推送數(shù)據(jù)庫(kù)到其它倉(cāng)庫(kù)的話.
這使得我們使用 Git 成為一個(gè)安心愉悅的過(guò)程,因?yàn)槲覀兩钪梢员M情做各種嘗試,而沒(méi)有把事情弄糟的危險(xiǎn).更深度探討 Git 如何保存數(shù)據(jù)及恢復(fù)丟失數(shù)據(jù)的話題,請(qǐng)參考撤消操作.
三種狀態(tài)
好,請(qǐng)注意.如果你希望后面的學(xué)習(xí)更順利,記住下面這些關(guān)于 Git 的概念. Git 有三種狀態(tài),你的文件可能處于其中之一:已提交(committed)、已修改(modified)和已暫存(staged).已提交表示數(shù)據(jù)已經(jīng)安全的保存在本地?cái)?shù)據(jù)庫(kù)中.已修改表示修改了文件,但還沒(méi)保存到數(shù)據(jù)庫(kù)中.已暫存表示對(duì)一個(gè)已修改文件的當(dāng)前版本做了標(biāo)記,使之包含在下次提交的快照中.
由此引入 Git 項(xiàng)目的三個(gè)工作區(qū)域的概念:Git 倉(cāng)庫(kù)、工作目錄以及暫存區(qū)域.
工作目錄、暫存區(qū)域以及 Git 倉(cāng)庫(kù).
Git 倉(cāng)庫(kù)目錄是 Git 用來(lái)保存項(xiàng)目的元數(shù)據(jù)和對(duì)象數(shù)據(jù)庫(kù)的地方.這是 Git 中最重要的部分,從其它計(jì)算機(jī)克隆倉(cāng)庫(kù)時(shí),拷貝的就是這里的數(shù)據(jù).
工作目錄是對(duì)項(xiàng)目的某個(gè)版本獨(dú)立提取出來(lái)的內(nèi)容.這些從 Git 倉(cāng)庫(kù)的壓縮數(shù)據(jù)庫(kù)中提取出來(lái)的文件,放在磁盤(pán)上供你使用或修改.
暫存區(qū)域是一個(gè)文件,保存了下次將提交的文件列表信息,一般在 Git 倉(cāng)庫(kù)目錄中.有時(shí)候也被稱作“索引”,不過(guò)一般說(shuō)法還是叫暫存區(qū)域.
對(duì)于任何一個(gè)文件,在 Git 內(nèi)都只有三種狀態(tài):
中文 | 英文 | 含義 |
已提交 | committed | 已提交表示該文件已經(jīng)被安全地保存在本地?cái)?shù)據(jù)庫(kù)中了 |
已修改 | modified | 已修改表示修改了某個(gè)文件,但還沒(méi)有提交保存 |
已暫存 | staged | 已暫存表示把已修改的文件放在下次提交時(shí)要保存的清單中 |
git中還有三類(lèi)常用對(duì)象(實(shí)際不止三種),理解這三類(lèi)對(duì)象也很重要.分別為:
blob,用于表示一個(gè)文件
tree,用于表示一個(gè)目錄,索引到若干文件或子目錄
commit,用于表示一次提交(commit)
所有對(duì)象都會(huì)以文件的形式保存在.git/objects目錄,一個(gè)對(duì)象一個(gè)文件.
目錄? ? 用法
git 目錄? ? 它是 Git 用來(lái)保存元數(shù)據(jù)和對(duì)象數(shù)據(jù)庫(kù)的地方.該目錄非常重要,每次克隆鏡像倉(cāng)庫(kù)的時(shí)候,實(shí)際拷貝的就是這個(gè)目錄里面的數(shù)據(jù).
工作目錄? ? 從項(xiàng)目中取出某個(gè)版本的所有文件和目錄,用以開(kāi)始后續(xù)工作的叫做工作目錄.這些文件實(shí)際上都是從 git 目錄中的壓縮對(duì)象數(shù)據(jù)庫(kù)中提取出來(lái)的,接下來(lái)就可以在工作目錄中對(duì)這些文件進(jìn)行編輯
暫存區(qū)域? ? 所謂的暫存區(qū)域只不過(guò)是個(gè)簡(jiǎn)單的文件,一般都放在 git 目錄中.有時(shí)候人們會(huì)把這個(gè)文件叫做索引文件,不過(guò)標(biāo)準(zhǔn)說(shuō)法還是叫暫存區(qū)域.
基本的 Git 工作流程如下:
1.在工作目錄中修改文件.
2.暫存文件,將文件的快照放入暫存區(qū)域.
3.提交更新,找到暫存區(qū)域的文件,將快照永久性存儲(chǔ)到 Git 倉(cāng)庫(kù)目錄.
如果 Git 目錄中保存著的特定版本文件,就屬于已提交狀態(tài).如果作了修改并已放入暫存區(qū)域,就屬于已暫存狀態(tài).如果自上次取出后,作了修改但還沒(méi)有放到暫存區(qū)域,就是已修改狀態(tài).在Git 基礎(chǔ)一章,你會(huì)進(jìn)一步了解這些狀態(tài)的細(xì)節(jié),并學(xué)會(huì)如何根據(jù)文件狀態(tài)實(shí)施后續(xù)操作,以及怎樣跳過(guò)暫存直接提交.
Git 使用規(guī)范
特別提醒:
使用Git過(guò)程中,必須通過(guò)創(chuàng)建分支進(jìn)行開(kāi)發(fā),堅(jiān)決禁止在主干分支上直接開(kāi)發(fā).review的同事有責(zé)任檢查其他同事是否遵循分支規(guī)范.
在Git中,默認(rèn)是不會(huì)提交空目錄的,如果想提交某個(gè)空目錄到版本庫(kù)中,需要在該目錄下新建一個(gè) .gitignore 的空白文件,就可以提交了
【代碼回溯注意】把外部文件納入到自己的 Git 分支來(lái)的時(shí)候一定要記得是先比對(duì),確認(rèn)所有修改都是自己修改的,然后再納入.不然,容易出現(xiàn)代碼回溯
【代碼回溯注意】多人協(xié)作時(shí),不要各自在自己的 Git 分支開(kāi)發(fā),然后發(fā)文件合并.正確的方法應(yīng)該是開(kāi)一個(gè)遠(yuǎn)程分支,然后一起在遠(yuǎn)程分支里協(xié)作.不然,容易出現(xiàn)代碼回溯(即別人的代碼被覆蓋的情況)
【代碼回溯注意】每個(gè)人提交代碼是一定要 git diff 看提交的東西是不是都是自己修改的.如果有不是自己修改的內(nèi)容,很可能就是代碼回溯
【代碼回溯注意】review 代碼的時(shí)候如果看到有被刪除掉的代碼,一定要確實(shí)是否是寫(xiě)代碼的同事自己刪除的.如果不是,很可能就是代碼回溯
分支合并及上線
步驟 | Git 操作 |
克隆代碼 | git clone 遠(yuǎn)程代碼 |
創(chuàng)建分支 | git checkout -b branch_name |
在分支中開(kāi)發(fā) | 無(wú) |
review代碼 | 無(wú) |
第一輪測(cè)試 | 無(wú) |
添加代碼到分支的暫存區(qū) | git add somefile |
提交代碼到分支 | git commit -m "本次提交的注釋" |
切換到主版本 | git checkout master |
獲取遠(yuǎn)程最新代碼 | git pull origin master |
合并某分支到master分支 | git merge branch_name |
解決合并時(shí)產(chǎn)生的沖突 請(qǐng)參考分支合并時(shí)沖突的解決 | 無(wú) |
第二輪測(cè)試 | 無(wú) |
準(zhǔn)備上線文檔 | 無(wú) |
獲取遠(yuǎn)程最新代碼 | git pull origin master |
推送master分支 | git push origin master |
通知上線 | 無(wú) |
沒(méi)有問(wèn)題了刪除本地分支 | git branch -d branch_name |
配置 Git
以下命令為配置 Git 相關(guān)信息,以下兩項(xiàng)必須要配置,會(huì)出現(xiàn)在每次提交的信???里.
git config --global user.name? "John" #規(guī)定為姓名全拼
git config --global user.email "John@linuxidc.com" #規(guī)定為公司郵箱
git config --global merge.tool "meld"? ? #可視化的合并工具
git config --global color.ui? true # 使用git默認(rèn)的配色方案,推薦
git config --global --list # 查看配置信息
git config --global user.name # 查看 user.name 的配置信息Git的功能特性:
從一般開(kāi)發(fā)者的角度來(lái)看,git有以下功能:
12345678 1、從服務(wù)器上克隆完整的Git倉(cāng)庫(kù)(包括代碼和版本信息)到單機(jī)上.
2、在自己的機(jī)器上根據(jù)不同的開(kāi)發(fā)目的,創(chuàng)建分支,修改代碼.
3、在單機(jī)上自己創(chuàng)建的分支上提交代碼.
4、在單機(jī)上合并分支.
5、把服務(wù)器上最新版的代碼fetch下來(lái),然后跟自己的主分支合并.
6、生成補(bǔ)丁(patch),把補(bǔ)丁發(fā)送給主開(kāi)發(fā)者.
7、看主開(kāi)發(fā)者的反饋,如果主開(kāi)發(fā)者發(fā)現(xiàn)兩個(gè)一般開(kāi)發(fā)者之間有沖突(他們之間可以合作解決的沖突),就會(huì)要求他們先解決沖突,然后再由其中一個(gè)人提交.如果主開(kāi)發(fā)者可以自己解決,或者沒(méi)有沖突,就通過(guò).
8、一般開(kāi)發(fā)者之間解決沖突的方法,開(kāi)發(fā)者之間可以使用pull 命令解決沖突,解決完沖突之后再向主開(kāi)發(fā)者提交補(bǔ)丁.
從主開(kāi)發(fā)者的角度(假設(shè)主開(kāi)發(fā)者不用開(kāi)發(fā)代碼)看,git有以下功能:
123 1、查看郵件或者通過(guò)其它方式查看一般開(kāi)發(fā)者的提交狀態(tài).
2、打上補(bǔ)丁,解決沖突(可以自己解決,也可以要求開(kāi)發(fā)者之間解決以后再重新提交,如果是開(kāi)源項(xiàng)目,還要決定哪些補(bǔ)丁有用,哪些不用).
3、向公共服務(wù)器提交結(jié)果,然后通知所有開(kāi)發(fā)人員.
優(yōu)點(diǎn):
? ? 適合分布式開(kāi)發(fā),強(qiáng)調(diào)個(gè)體.
? ? 公共服務(wù)器壓力和數(shù)據(jù)量都不會(huì)太大.
? ? 速度快、靈活.
? ? 任意兩個(gè)開(kāi)發(fā)者之間可以很容易的解決沖突.
? ? 離線工作.
缺點(diǎn):
? ? 資料少(起碼中文資料很少).
? ? 學(xué)習(xí)周期相對(duì)而言比較長(zhǎng).
? ? 不符合常規(guī)思維.
? ? 代碼保密性差,一旦開(kāi)發(fā)者把整個(gè)庫(kù)克隆下來(lái)就可以完全公開(kāi)所有代碼和版本信息.
部署 Git
依賴庫(kù):
yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc xmlto docbook2x perl-ExtUtils-Embed texinfo
yum install -y tk zlib-devel openssl-devel perl cpio expat-devel gettext-devel asciidoc xmlto openjade perl-XML-SAX
docbook2x 這個(gè)庫(kù)需要額外安裝123 wget ftp://ftp.is.co.za/mirror/Fedora.RedHat.com/epel/6/x86_64/docbook2X-0.8.8-1.el6.x86_64.rpm
rpm -ivh docbook2X-0.8.8-1.el6.x86_64.rpm
ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi
當(dāng)你安裝好所有的必要依賴,你可以繼續(xù)從幾個(gè)地方來(lái)取得最新發(fā)布版本的 tar 包.
?
你可以從
Kernel.org 網(wǎng)站獲取,網(wǎng)址為? https://www.kernel.org/pub/software/scm/git,
GitHub 網(wǎng)站上的鏡像來(lái)獲得,網(wǎng)址為 https://github.com/git/git/releases.
通常在 GitHub 上的是最新版本,但 kernel.org 上包含有文件下載簽名,如果你想驗(yàn)證下載正確性的話會(huì)用到.編譯安裝:wget https://www.kernel.org/pub/software/scm/git/git-2.10.2.tar.gz --no-check-certificate
?
tar -zxvf git-2.10.2.tar.gz
cd git-2.10.2
make clean 如果時(shí)間長(zhǎng),出現(xiàn)warning,可能是系統(tǒng)時(shí)間問(wèn)題
[root@John git-2.10.2]# make configure
GIT_VERSION = 2.10.2
? ? GEN configure
?
./configure --prefix=/usr
make all doc info
make install install-doc install-html install-info
創(chuàng)建新倉(cāng)庫(kù)
?
獲取與創(chuàng)建項(xiàng)目
?
你得先有一個(gè) Git 倉(cāng)庫(kù),才能用它進(jìn)行操作.倉(cāng)庫(kù)是 Git 存放你要保存的快照的數(shù)據(jù)的地方.
?
擁有一個(gè) Git 倉(cāng)庫(kù)的途徑有兩種.在已有的目錄中,初始化一個(gè)新的,
其一. 比如一個(gè)新的項(xiàng)目,或者一個(gè)已存在的項(xiàng)目,但該項(xiàng)目尚未有版本控制.
如果你想要復(fù)制一份別人的項(xiàng)目, 或者與別人合作某個(gè)項(xiàng)目,也可以從一個(gè)公開(kāi)的 Git 倉(cāng)庫(kù)克隆,
其二.本章將對(duì)兩者都做介紹.
?
創(chuàng)建新文件夾,打開(kāi),然后執(zhí)行
git init
?
以創(chuàng)建新的 git 倉(cāng)庫(kù).
[root@John /]# ls -a
.? .autofsck? ? bin? cgroup? etc? home? lib64? ? ? media? mnt? opt? root? selinux? sys? usr? www
..? .autorelabel? boot? dev? ? .git? lib? lost+found? misc? net? proc? sbin? srv? ? ? tmp? var
[root@John /]# cd .git/
[root@John .git]# ls
branches? config? description? HEAD? hooks? info? objects? refs
該目錄下可能還會(huì)包含其他文件,不過(guò)對(duì)于一個(gè)全新的 git init 版本庫(kù),這將是你看到的默認(rèn)結(jié)構(gòu).
?
description 文件僅供 GitWeb 程序使用,我們無(wú)需關(guān)心.
?
config 文件包含項(xiàng)目特有的配置選項(xiàng).
?
info? 目錄包含一個(gè)全局性排除(global exclude)文件,
? ? 用以放置那些不希望被記錄在 .gitignore 文件中的忽略模式(ignored patterns).
? ? ?
hooks 目錄包含客戶端或服務(wù)端的鉤子腳本(hook scripts),
? ? 在 Git 鉤子 中這部分話題已被詳細(xì)探討過(guò).
剩下的四個(gè)條目很重要:
HEAD? 文件、(尚待創(chuàng)建的)index 文件,和 objects 目錄、refs 目錄.
這些條目是 Git 的核心組成部分.
objects? 目錄存儲(chǔ)所有數(shù)據(jù)內(nèi)容;
refs? ? 目錄存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象的指針;
HEAD? ? 文件指示目前被檢出的分支;
index? ? 文件保存暫存區(qū)信息.
我們將詳細(xì)地逐一檢視這四部分,以期理解 Git 是如何運(yùn)轉(zhuǎn)的.
恭喜,現(xiàn)在你就有了一個(gè) Git 倉(cāng)庫(kù)的架子,可以開(kāi)始快照你的項(xiàng)目了.
簡(jiǎn)而言之,用 git init 來(lái)在目錄中創(chuàng)建新的 Git 倉(cāng)庫(kù).
你可以在任何時(shí)候、任何目錄中這么做,完全是本地化的.
用戶信息:
當(dāng)安裝完 Git 應(yīng)該做的第一件事就是設(shè)置你的用戶名稱與郵件地址.
這樣做很重要,因?yàn)槊恳粋€(gè) Git 的提交都會(huì)使用這些信息,并且它會(huì)寫(xiě)入到你的每一次提交中,不可更改:
[root@John git-2.10.2]# git config --global user.name 'John Doe'
[root@John git-2.10.2]# git config --global user.email XXOO@126.com
再次強(qiáng)調(diào),如果使用了 --global 選項(xiàng),那么該命令只需要運(yùn)行一次,因?yàn)橹鬅o(wú)論你在該系統(tǒng)上做任何事情, Git 都會(huì)使用那些信息. 當(dāng)你想針對(duì)特定項(xiàng)目使用不同的用戶名稱與郵件地址時(shí),可以在那個(gè)項(xiàng)目目錄下運(yùn)行沒(méi)有 --global 選項(xiàng)的命令來(lái)配置.
很多 GUI 工具都會(huì)在第一次運(yùn)行時(shí)幫助你配置這些信息.
獲取幫助
若你使用 Git 時(shí)需要獲取幫助,有三種方法可以找到 Git 命令的使用手冊(cè):
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
例如,要想獲得 config 命令的手冊(cè),執(zhí)行
$ git help config
這些命令很棒,因?yàn)槟汶S時(shí)隨地可以使用而無(wú)需聯(lián)網(wǎng).
如果你覺(jué)得手冊(cè)或者本書(shū)的內(nèi)容還不夠用,你可以嘗試在 Freenode IRC 服務(wù)器( irc.freenode.net )的 #git 或 #github 頻道尋求幫助.
這些頻道經(jīng)常有上百人在線,他們都精通 Git 并且樂(lè)于助人.
總結(jié)
你應(yīng)該已經(jīng)對(duì) Git 是什么、Git 與你可能正在使用的集中式版本控制系統(tǒng)有何區(qū)別等問(wèn)題有了基本的了解.
現(xiàn)在,在你的個(gè)人系統(tǒng)中應(yīng)該也有了一份能夠工作的 Git 版本.
是時(shí)候開(kāi)始學(xué)習(xí)有關(guān) Git 的基礎(chǔ)知識(shí)了.
基本用法
上面的四條命令在工作目錄、暫存目錄(也叫做索引)和倉(cāng)庫(kù)之間復(fù)制文件.
git add files 把當(dāng)前文件放入暫存區(qū)域.
git commit 給暫存區(qū)域生成快照并提交.
git reset -- files 用來(lái)撤銷(xiāo)最后一次git add files,你也可以用git reset? ? 撤銷(xiāo)所有暫存區(qū)域文件.
git checkout -- files 把文件從暫存區(qū)域復(fù)制到工作目錄,用來(lái)丟棄本地修改.
你可以用 git reset -p, git checkout -p, or? git add -p進(jìn)入交互模式.
也可以跳過(guò)暫存區(qū)域直接從倉(cāng)庫(kù)取出文件或者直接提交代碼.
git commit -a 相當(dāng)于運(yùn)行 git add? ? 把所有當(dāng)前目錄下的文件加入暫存區(qū)域再運(yùn)行.git commit.
git commit files 進(jìn)行一次包含最后一次提交加上工作目錄中文件快照的提交.并且文件被添加到暫存區(qū)域.
git checkout HEAD -- files 回滾到復(fù)制最后一次提交.
git基本命令:
設(shè)置用戶名:git config --global user.name"your name"
設(shè)置Email:git config --global user.email"email name"
創(chuàng)建目錄:mkdir name
退回目錄:cd name
顯示當(dāng)前目錄:pwd
?
把目錄變成git可管理的倉(cāng)庫(kù):git init
添加文件到倉(cāng)庫(kù):git add 文件名
提交文件到倉(cāng)庫(kù):git commit
掌握倉(cāng)庫(kù)當(dāng)前的狀態(tài):git status
查看具體修改內(nèi)容:git diff
?
查看歷史記錄:git log
回退版本:git reset --hard HEAD^
恢復(fù)回退的版本:git reset --hard 版本號(hào)
記錄每一次記錄:git reflog
把readme.txt文件在工作區(qū)的修改全部撤銷(xiāo):git checkout --文件名
刪除一個(gè)文件:git rm 文件名
版本庫(kù)里的版本替換工作區(qū)的版本:git checkout -- 文件名
?
創(chuàng)建SSH key:ssh-keygen -t rsa -C "郵箱名稱"
本地關(guān)聯(lián)遠(yuǎn)程數(shù)據(jù)庫(kù):git remote add origin git@git.linuxidc.net:John.com/testGit.git
git@git.linuxidc.net:John/newFile.git
git@git.linuxidc.net:John/helloWord.git
?
將本地?cái)?shù)據(jù)推送到遠(yuǎn)程倉(cāng)庫(kù)中:git push -u origin master(注意本地倉(cāng)庫(kù)名稱一定跟遠(yuǎn)程倉(cāng)庫(kù)名稱相同)
將遠(yuǎn)程倉(cāng)庫(kù)中的數(shù)據(jù)下載到本地倉(cāng)庫(kù):git clone? git@git.linuxidc.net:John.com/gitSkills.git
?
創(chuàng)建并切換分支:git checkout -b 分支名稱
查詢所有分支:git branch
切換分支:git checkout 分支名稱
合并指定分支到當(dāng)前分支:git merge dev
刪除分支:git branch -d 分支名稱
合并分支:git merge 分支名稱
?
合并分支禁用Fast forward:git merger --no-ff -m "注釋" dev
?把當(dāng)前現(xiàn)場(chǎng)“儲(chǔ)存起來(lái)”:git stash
查看工作現(xiàn)場(chǎng)列表:git stash list
恢復(fù)現(xiàn)場(chǎng):1? git stash apply? stash內(nèi)容并不刪除,你需要用git stash drop來(lái)刪除;
? ? ? ? ? 2? git stash pop? 恢復(fù)的同時(shí)把stash內(nèi)容也刪了
強(qiáng)行刪除分支:git branch -D 分支名
將分支推送到遠(yuǎn)程倉(cāng)庫(kù)的對(duì)應(yīng)分支上:git push origin 分支名稱
抓取最新的提交從遠(yuǎn)程倉(cāng)庫(kù)中:git pull
建立本地分支和遠(yuǎn)程分支的關(guān)聯(lián):git branch --set-upstream dev origin/dev
在本地創(chuàng)建和遠(yuǎn)程分支對(duì)應(yīng)的分支:git checkout -b branch-名字 origin/branch-名字
?
創(chuàng)建標(biāo)簽:git tag 標(biāo)簽名
查看標(biāo)簽:git tag
對(duì)指定的commit打標(biāo)簽:git tag commitId?
創(chuàng)建帶說(shuō)明的標(biāo)簽:git tag -a 標(biāo)簽名 -m "說(shuō)明" commit的ID
刪除標(biāo)簽:git tag -d 標(biāo)簽名
推送標(biāo)簽名到遠(yuǎn)程:git push origin 標(biāo)簽名
一次性推送所有的標(biāo)簽名:git push origin --tags
從遠(yuǎn)程倉(cāng)庫(kù)刪除標(biāo)簽:gitpush origin :refs/tags/標(biāo)簽名
?
?
為命令配置別名:git config --global alias.st status
git總結(jié):
注意事項(xiàng):
#1. 多提交(相當(dāng)于多保存,多^S):
在Git中任何已提交的東西幾乎總是可以恢復(fù)的. 甚至那些被刪除的分支中的提交或使用 --amend 選項(xiàng)覆蓋的提交也可以恢復(fù). 然而,任何你未提交的東西丟失后很可能再也找不到了.
#2. 拉取別人數(shù)據(jù)之前要提交.減少工作區(qū),暫存區(qū)數(shù)據(jù)沖突的可能.
#3. 推送之前先拉取.即將自已的版本做為最新之前,要先合并別人的修改.
#4. 切換分支前要提交,否則有可能數(shù)據(jù)丟失.即保存在此分支的修改.
#5. 合并分支之前要提交.拉取視情況而定(建議拉取).
#6. 慎用 git checkout -- <file>
撤消對(duì)文件的修改(拷貝了另一個(gè)文件來(lái)覆蓋它), 除非你確實(shí)清楚不想要那個(gè)文件了,否則不要使用這個(gè)命令.
#7. 嘗試讓每一個(gè)提交成為一個(gè)邏輯上的獨(dú)立變更集.一個(gè)問(wèn)??一個(gè)提交,這個(gè)提交包含了這個(gè)問(wèn)題的全部修改.
#8. 最后一件要牢記的事是提交信息. 有一個(gè)創(chuàng)建優(yōu)質(zhì)提交信息的習(xí)慣會(huì)使 Git 的使用與協(xié)作容易的多.
#9. 變基:只對(duì)尚未推送或分享給別人的本地修改執(zhí)行變基操作清理歷史,從不對(duì)已推送至別處的提交執(zhí)行變基操作.
#10. SourceTree GitFlow快捷鍵(mac):alt + 花 + F 異常驚艷
?
?
?
環(huán)境搭建
#1:安裝
Mac: Mac蘋(píng)果系統(tǒng): git2.10.1 + sourceTree2.3.2
Win: Windows 64 bit: git2.5.1 + TortoiseGit + zh
?
#2:配置用戶信息
Win: 設(shè)置 ---> Git
Mac: sourcetree ---> 偏好設(shè)置 ----> 通用
?
#3: 配置密鑰
Win: ????
Mac: $ ssh -keygen -t rsa -C youremail@example.com (一路yes或null就可以)
會(huì)存儲(chǔ)在:/Users/mac/.ssh/*.pub
?
#4: 避免每次輸入密碼(未驗(yàn)證)
git config --global credential.helper cache
?
#5:倉(cāng)庫(kù)劃分和SVN相同.
Art:加工 3dMax, ps的資源成為unity使用的 *.ab
Design: 提供服務(wù)器和客戶端用的表
Public.ResPackage: 存Art生成的資源
Public.PackedVersionConfig: 制做和存儲(chǔ)version.txt文件及熱更新文件
Public.TTDS_apk:存安裝包
Server:服務(wù)器
Client:客戶端
?
#6: Clone工程
a. 創(chuàng)建目標(biāo)目錄
b. Win: ----
Mac: git clone client@10.1.10.100:tiantiandiansha.git
c. 顯示隱藏文件 + 把(.git + 其它調(diào)整到合適位置)
d. 用工具打開(kāi):菜單---> 倉(cāng)庫(kù)---> git flow ---> 初使化倉(cāng)庫(kù)
確認(rèn)本工程在 Develop分支
?
?
分支
#1: 分支的劃分和目的(git flow)
a. 線上問(wèn)題
master[主干]: 備份線上版本.
hotfix[臨時(shí)]: 修復(fù)線上bug.
b. 日常開(kāi)發(fā)
develop[主干]: 功能集成.
features[臨時(shí)]: 日常開(kāi)發(fā).
c. 發(fā)布
master[主干]: 根據(jù)Tag發(fā)布版本.
release[臨時(shí)]: develop某些功能達(dá)到可發(fā)布程度,創(chuàng)建此分支,把功能集成到master,加Tag以備發(fā)版打包.
?
?
#2:在哪個(gè)分支上High
a. 具體操做都在分支中完成,主干只負(fù)責(zé)數(shù)據(jù)集成.減少?zèng)_突方便并行.
把主干當(dāng)做單純的數(shù)據(jù)源,分支是一個(gè)獨(dú)立的空間.一個(gè)操做可以表述為,為達(dá)到一個(gè)目的從某個(gè)數(shù)據(jù)源取得數(shù)據(jù)、創(chuàng)建空間;然后在這個(gè)獨(dú)立的空間里對(duì)其進(jìn)行處理;處理完成之后再更新到某些數(shù)據(jù)源.一個(gè)操做結(jié)束.此分支也完成了他的使命.
b. features:日常功能開(kāi)發(fā) + develop上的bug修復(fù).
c. hotfix: 線上bug修復(fù).
在master主干根據(jù)Tag創(chuàng)建,完成之后是否合并到develop或master需要根據(jù)develp或master的后續(xù)版本是否已修改來(lái)定.未修改的需要合并到develop+master.已修改的可以直接在hotfix分支打包發(fā)布.另外是否合并還要考慮是否是臨時(shí)性暴力修復(fù).
注意:hotfix分支是從master舊的版本創(chuàng)建來(lái)的,合并時(shí)請(qǐng)注意莫回檔.
d. release:目的是把develop成熟的功能合并到master并打Tag.供后面按需發(fā)布.不在release分支做bug修復(fù).
e. bug修復(fù):
develop主干bug:由features分支修復(fù).
master線上bug:由hotfix分支修復(fù).
master未上線bug:由release 或 features + release修復(fù)(只果只用features需要手動(dòng)將分支合并到master).
?
#3:分支切換
a. 未跟蹤的文件:顯示在了工作區(qū).因未納入任何分支,所以所有分支都可填加.
在目標(biāo)分區(qū)提交了原分區(qū)未暫存的文件,切換回原分支,原未暫存文件丟失.
b. 已暫存未提交(新增加的文件,開(kāi)始跟蹤):
不放棄本地變更,到目標(biāo)分支時(shí)還在已暫存未提交狀態(tài)(sourceTree功能,將原分支的暫存狀態(tài)copy過(guò)來(lái)了).
放棄本地變更,目標(biāo)分支不存在已暫存未提交文件.再切回原分支原已暫存未提交文件丟失.(放棄本地變更==放棄填加文件)
已暫存未提交(提交后再次修改):
不放棄本地變更, sourTree不允許.提示,先提交或隱藏(stash),之后再切換.
放棄本地變更,目標(biāo)分支不存在已暫存未提交文件.再切回原分支,原已暫存的修改丟失.(放棄本地變更==放棄已暫存文件修改)
說(shuō)明:切換分支時(shí),將丟棄原分支已暫存的修改.
c. 已提交的文件:原分支已提交的文件不會(huì)帶入新的分支.
?
請(qǐng)牢記:當(dāng)你切換分支的時(shí)候,Git 會(huì)重置你的工作目錄,使其看起來(lái)像回到了你在那個(gè)分支上最后一次提交的樣子. Git 會(huì)自動(dòng)添加、刪除、修改文件以確保此時(shí)你的工作目錄和這個(gè)分支最后一次提交時(shí)的樣子一模一樣.
?
總結(jié):切換分支時(shí),應(yīng)保存(提交或隱藏)本分支的操作.否則切換回來(lái)后,未保存的內(nèi)容將丟失. 因?yàn)楫?dāng)前工作區(qū)和暫存區(qū)只有一份,切換分支時(shí)要清除屬于原分支的內(nèi)容.未跟蹤或首次暫存內(nèi)容可進(jìn)入新分支是工具的優(yōu)化.
?
#4: 分支合并
何時(shí)會(huì)合并:
a. 用git pull從遠(yuǎn)端拉取時(shí)會(huì)合并(git pull = git fetch + git merge).
b. 主動(dòng)合并分支時(shí):如git flow的 features release 完成時(shí).
?
合并方法:
在 Git 中整合來(lái)自不同分支的修改主要有兩種方法:merge 以及 rebase(變基)
a. 未分叉情況:快進(jìn)方式(fast-forward)
由于當(dāng)前 master 分支所指向的提交是你當(dāng)前提交(有關(guān) hotfix 的提交)的直接上游,所以 Git 只是簡(jiǎn)單的將指針向前移動(dòng). 換句話說(shuō),當(dāng)你試圖合并兩個(gè)分支時(shí),如果順著一個(gè)分支走下去能夠到達(dá)另一個(gè)分支,那么 Git 在合并兩者的時(shí)候,只會(huì)簡(jiǎn)單的將指針向前推進(jìn)(指針右移),因?yàn)檫@種情況下的合并操作沒(méi)有需要解決的分歧——這就叫做 “快進(jìn)(fast-forward)”
b. 分叉情況:
在這種情況下,你的開(kāi)發(fā)歷史從一個(gè)更早的地方開(kāi)始分叉開(kāi)來(lái)(diverged). 因?yàn)?master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些額外的工作. 出現(xiàn)這種情況的時(shí)候,Git 會(huì)使用兩個(gè)分支的末端所指的快照(C4 和 C5)以及這兩個(gè)分支的工作祖先(C2),做一個(gè)簡(jiǎn)單的三方合并.
和之間將分支指針向前推進(jìn)所不同的是,Git 將此次三方合并的結(jié)果做了一個(gè)新的快照并且自動(dòng)創(chuàng)建一個(gè)新的提交指向它. 這個(gè)被稱作一次合并提交,它的特別之處在于他有不止一個(gè)父提交.
?
沖突:
a. 只有合并時(shí)才會(huì)有沖突.
b. 文件沖突時(shí),Git已經(jīng)完成了合并(有沖突標(biāo)記,此時(shí)沖突的文件應(yīng)是已修改未暫存狀態(tài)),但是沒(méi)有自動(dòng)地創(chuàng)建一個(gè)新的合并提交.此時(shí)Git會(huì)暫停下來(lái),等待你去解決合并產(chǎn)生的沖突.
在你解決了所有文件里的沖突之后,對(duì)每個(gè)文件使用 git add 命令來(lái)將其標(biāo)記為沖突已解決. 一旦暫存這些原本有沖突的文件,Git 就會(huì)將它們標(biāo)記為沖突已解決.
?
變基:
a. 原理:
它的原理是首先找到這兩個(gè)分支(即當(dāng)前分支 experiment、變基操作的目標(biāo)基底分支 master)的最近共同祖先 C2,然后對(duì)比當(dāng)前分支相對(duì)于該祖先的歷次提交,提取相應(yīng)的修改并存為臨時(shí)文件,然后將當(dāng)前分支指向目標(biāo)基底 C3, 最后以此將之前另存為臨時(shí)文件的修改依序應(yīng)用.
這兩種整合方法(merge和rebase)的最終結(jié)果沒(méi)有任何區(qū)別,但是變基使得提交歷史更加整潔.
b. 風(fēng)險(xiǎn):
變基也并非完美無(wú)缺,要用它得遵守一條準(zhǔn)則:不要對(duì)在你的倉(cāng)庫(kù)外有副本的分支執(zhí)行變基.
總的原則是,只對(duì)尚未推送或分享給別人的本地修改執(zhí)行變基操作清理歷史,從不對(duì)已推送至別處的提交執(zhí)行變基操作,這樣,你才能享受到兩種方式帶來(lái)的便利.
?
?
發(fā)版相關(guān)
a. 使用 master分支發(fā)版(舊版本 + 新版本),所以需將開(kāi)發(fā)分支(develop)的修改合并到master.
b. 哪個(gè)倉(cāng)庫(kù)需合并到master:
Art: ??(負(fù)責(zé)生成 AssesBundle的人?)
Design: ??
Server: 客戶端發(fā)版的人
Client:服務(wù)器發(fā)版的人
Public: 客戶端發(fā)版的人 或 制做熱更新包的人
c. 合并到master分支的時(shí)間:
Art: 成功發(fā)版后和加Tag一起
Design: 成功發(fā)版后和加Tag一起
Public: 成功發(fā)版后和加Tag一起
Server: 發(fā)版結(jié)點(diǎn),開(kāi)發(fā)分支測(cè)試通過(guò)后.
Client:發(fā)版結(jié)點(diǎn),開(kāi)發(fā)分支測(cè)試通過(guò)后.
d. 加Tag:
成功發(fā)版后給master分支加Tag. 以備以后切換到此Tag當(dāng)時(shí)的版本改bug或發(fā)版本.
由合并到master的人加Tag.
注意:為保證根據(jù)Tag找到所有數(shù)據(jù),tag不能漏加,tag格式一致(至少含相同版本號(hào),精確到資源版本號(hào) 1.0.38.0.0 ).?
?
基礎(chǔ):
詳情請(qǐng)參考:https://git-scm.com/book/zh/v2
?
#1. 文件狀態(tài)及對(duì)應(yīng)的工作區(qū)
Git狀態(tài):已修改(modified),已暫存(staged),已提交(committed)----- 只管理已跟蹤文件
工作區(qū): 工作目錄, 暫存區(qū), Git倉(cāng)庫(kù)
文件狀態(tài):未跟蹤 已跟蹤(未修改,已修改,已暫存)
未跟蹤:新加入當(dāng)前分支,從未暫存(git add)過(guò)的文件.
已跟蹤:已提交到Git倉(cāng)庫(kù)或暫存過(guò)的文件
已跟蹤已暫存:暫存區(qū)中的文件(git add過(guò)).
已跟蹤已修改:工作區(qū)中的文件.
已跟蹤未修改:已提交到Git倉(cāng)庫(kù)的文件(git commit過(guò)).
?
#2. 暫存:
1. 暫存操作會(huì)為每一個(gè)文件計(jì)算校驗(yàn)和(使用SHA-1哈希算法)
2. 然后會(huì)把當(dāng)前版本的文件快照保存到Git倉(cāng)庫(kù)中(Git使用blob對(duì)象來(lái)保存它們)
3. 最終將校驗(yàn)和加入到暫存區(qū)域等待提交.
?
#3. 提交:
1. 創(chuàng)建樹(shù)對(duì)象并保存到Git倉(cāng)庫(kù):
Git會(huì)先計(jì)算當(dāng)前分支的每一個(gè)子目錄的校驗(yàn)和,然后在Git倉(cāng)庫(kù)中將這些校驗(yàn)和保存為樹(shù)對(duì)象.
2. 創(chuàng)建提交對(duì)象并保存到Git倉(cāng)庫(kù):
隨后,Git便會(huì)創(chuàng)建一個(gè)提交對(duì)象(commit object).提交對(duì)象保存的內(nèi)容:
a. 包含了作者的姓名和郵箱、提交時(shí)輸入的信息.
b. 指向它的父對(duì)象的指針.(首次提交產(chǎn)生的提交對(duì)象沒(méi)有父對(duì)象,普通提交有一個(gè)父對(duì)象,而由多個(gè)分支合并產(chǎn)生的提交對(duì)象有多個(gè)父對(duì)象)
c. 還包含指向1創(chuàng)建的樹(shù)對(duì)象(項(xiàng)目根目錄)的指針.
3. 注意:提交只提交暫存區(qū)中的文件(修改過(guò)但未暫存的文件不會(huì)被提交).
?
暫存提交之后:Git 倉(cāng)庫(kù)中有五個(gè)對(duì)象:
a. 三個(gè) blob 對(duì)象(暫存時(shí)保存的文件快照)
b. 一個(gè)樹(shù)對(duì)象(記錄著目錄結(jié)構(gòu)和 blob 對(duì)象索引)
c. 以及一個(gè)提交對(duì)象(包含著指向前述樹(shù)對(duì)象的指針和所有提交信息).
?
#4. 分支
a. Git的分支,其實(shí)本質(zhì)上僅僅是指向提交對(duì)象的可變指針(Tag是不變的指針).
b. HEAD: 在 Git 中,它是一個(gè)指針,指向當(dāng)前所在的本地分支(譯注:將 HEAD 想象為當(dāng)前分支的別名).
https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B
[個(gè)人理解]: 拉取,抓取,推送,都是對(duì)提交對(duì)象的下載上傳,分支進(jìn)度就是改變分支指針指向不同的對(duì)象.
?
#5. 抓?。篻it fetch [remote-name]
git fetch: 命令與一個(gè)遠(yuǎn)程的倉(cāng)庫(kù)交互,并且將遠(yuǎn)程倉(cāng)庫(kù)中有但是在當(dāng)前倉(cāng)庫(kù)的沒(méi)有的所有信息拉取下來(lái)然后存儲(chǔ)在你本地?cái)?shù)據(jù)庫(kù)中.?
?
#6. 拉?。?
a. git pull: 命令基本上就是 git fetch 和 git merge 命令的組合體.
b. 完整格式:git pull <遠(yuǎn)程主機(jī)名> <遠(yuǎn)程分支名>:<本地分支名>
b. git pull : Git從你指定的(當(dāng)前分支所跟蹤的)遠(yuǎn)程倉(cāng)庫(kù)中抓取內(nèi)容,然后馬上嘗試將其合并進(jìn)你所在的分支中.
?
#7. 推送:git push [remote-name] [branch-name]
a. git push: 計(jì)算你本地?cái)?shù)據(jù)庫(kù)與遠(yuǎn)程倉(cāng)庫(kù)的差異,然后將差異推送到另一個(gè)倉(cāng)庫(kù)中. 它需要有另一個(gè)倉(cāng)庫(kù)的寫(xiě)權(quán)限
?
#8. .git 目錄
這些條目是 Git 的核心組成部分.
objects: 目錄存儲(chǔ)所有數(shù)據(jù)內(nèi)容;
refs: 目錄存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象的指針;
HEAD: 文件指示目前被檢出的分支;
index: 文件保存暫存區(qū)信息.?
?
?
命令
?
git help
git init
git status
a. Untracked files: 未跟蹤的文件
b. Changes to be committed: (說(shuō)明是已暫存狀態(tài))
(use "git reset HEAD <file>..." to unstage)
c. Changes not staged for commit: (說(shuō)明已跟蹤文件的內(nèi)容發(fā)生了變化,但還沒(méi)有放到暫存區(qū))
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
d. You have unmerged paths.(合并沖突)
(fix conflicts and run "git commit")
e. All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
?
git status -s
??: 新添加的未跟蹤文件前面有 ?? 標(biāo)記
A : 新添加到暫存區(qū)中的文件前面有 A 標(biāo)記
MM: 修改過(guò)的文件前面有 M 標(biāo)記. 左M: 修改了并放入了暫存區(qū) 右M: 修改了還沒(méi)放入暫存區(qū).
兩位:左表暫存區(qū),右表工作區(qū)
說(shuō)明:-s 不顯示需推送的內(nèi)容,只涉及到工作區(qū)和暫存區(qū),Git倉(cāng)庫(kù)的狀態(tài)不顯示.
?
?
git add <文件|目錄> : (添加內(nèi)容到下一次提交中)
a. 開(kāi)始跟蹤新文件
b. 把已跟蹤(已修改)的文件放到暫存區(qū)
c. 合并時(shí)把有沖突的文件標(biāo)記為已解決狀態(tài)等
?
運(yùn)行了 git add 之后又作了修訂的文件,需要重新運(yùn)行 git add 把最新版本重新暫存起來(lái):
?
git reset HEAD <file>
說(shuō)明:取消暫存的文件
NOTE: 雖然在調(diào)用時(shí)加上 --hard 選項(xiàng)可以令 git reset 成為一個(gè)危險(xiǎn)的命令(譯注:可能導(dǎo)致工作目錄中所有當(dāng)前進(jìn)度丟失!),但本例中工作目錄內(nèi)的文件并不會(huì)被修改. 不加選項(xiàng)地調(diào)用 git reset 并不危險(xiǎn) — 它只會(huì)修改暫存區(qū)域.
?
?
git checkout -- <file>
說(shuō)明:撤消對(duì)文件的修改(拷貝了另一個(gè)文件來(lái)覆蓋它)
IMPORTANT:這是一個(gè)危險(xiǎn)的命令. 你對(duì)那個(gè)文件做的任何修改都會(huì)消失.除非你確實(shí)清楚不想要那個(gè)文件了,否則不要使用這個(gè)命令.
?
?
git diff
此命令比較的是工作目錄中當(dāng)前文件和暫存區(qū)域快照之間的差異, 也就是修改之后還沒(méi)有暫存起來(lái)的變化內(nèi)容.
請(qǐng)注意,git diff 本身只顯示尚未暫存的改動(dòng),而不是自上次提交以來(lái)所做??所有改動(dòng). 所以有時(shí)候你一下子暫存了所有更新過(guò)的文件后,運(yùn)行 git diff 后卻什么也沒(méi)有,就是這個(gè)原因.
git diff --staged(等同于 git diff --cached)
查看已暫存的將要添加到下次提交里的內(nèi)容.是暫存文件和已提交文件的比較.
?
git commit (這種方式會(huì)啟動(dòng)文本編輯器以便輸入本次提交的說(shuō)明)
git commit -m "Story 182: Fix benchmarks for speed"
請(qǐng)記住,提交時(shí)記錄的是放在暫存區(qū)域的快照. 任何還未暫存的仍然保持已修改狀態(tài),可以在下次提交時(shí)納入版本管理. 每一次運(yùn)行提交操作,都是對(duì)你項(xiàng)目作一次快照,以后可以回到這個(gè)狀態(tài),或者進(jìn)行比較.
git commit -a -m 'added new benchmarks' (git acm: git add + git commit -m)
git commit --amend
commit之后:版本修改將添加到歷史記錄
?
?
git rm PROJECTS.md(等于 git rm -f PROJECTS.md)
git rm --cached PROJECTS.md
git rm -f PROJECTS.md
目標(biāo)文件未被跟蹤:操做無(wú)效
目標(biāo)文件在暫存區(qū):
a. 無(wú)參:提示加參數(shù) --cached 或 -f
b. -f: 從暫存區(qū)中刪除,也從本地文件系統(tǒng)中刪除.
c. --cached: 從暫存區(qū)中刪除,但不從本地文件系統(tǒng)刪除.
?
目標(biāo)文件已提交在Git倉(cāng)庫(kù)中:
a. 無(wú)參或加-f參數(shù):即從倉(cāng)庫(kù)中刪除,也從本地文件系統(tǒng)中刪除.
b. --cached: 從倉(cāng)庫(kù)中刪除,但不從本地文件系統(tǒng)刪除.
?
?
git mv file_from file_to
運(yùn)行 git mv 就相當(dāng)于運(yùn)行了下面三條命令:
$ mv README.md README
$ git rm README.md
$ git add README
?
?
git log -p -2
git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
git log --pretty=format:"%h %s" --graph
git log --since=2.weeks
git log -Sfunction_name
git log --pretty="%h - %s" --graph -- 1.txt
git log --oneline --decorate 查看各個(gè)分支當(dāng)前所指的對(duì)象
?
?
git clone https://github.com/schacon/ticgit
git clone git@github.com:mojombo/grit.git NewName
?
?
git remote
git remote -v
git remote show [remote-name] 查看遠(yuǎn)程倉(cāng)庫(kù)
git remote add <shortname> <url> 添加遠(yuǎn)程倉(cāng)庫(kù)
git remote rm paul 遠(yuǎn)程倉(cāng)庫(kù)的移除
git remote rename pb paul 遠(yuǎn)程倉(cāng)庫(kù)的重命名
?
?
git fetch [remote-name] 從遠(yuǎn)程倉(cāng)庫(kù)中抓取與拉取
a. 這個(gè)命令查找 “origin” 是哪一個(gè)服務(wù)器(在本例中,它是 git.ourcompany.com), 從中抓取本地沒(méi)有的數(shù)據(jù),
b. 并且更新本地?cái)?shù)據(jù)庫(kù).
c. 移動(dòng) origin/master 指針指向新的、更新后的位置.
?
當(dāng) git fetch 命令從服務(wù)器上抓取本地沒(méi)有的數(shù)據(jù)時(shí),它并不會(huì)修改工作目錄中的內(nèi)容. 它只會(huì)獲取數(shù)據(jù)然后讓你自己合并.
?
要特別注意的一點(diǎn)是當(dāng)抓取到新的遠(yuǎn)程跟蹤分支時(shí),本地不會(huì)自動(dòng)生成一份可編輯的副本(拷貝). 換一句話說(shuō),這種情況下,不會(huì)有一個(gè)新的 serverfix 分支 - 只有一個(gè)不可以修改的 origin/serverfix 指針.
可以運(yùn)行 git merge origin/serverfix 將這些工作合并到當(dāng)前所在的分支. 如果想要在自己的 serverfix 分支上工作,可以將其建立在遠(yuǎn)程跟蹤分支之上
?
?
?
git push [remote-name] [branch-name]
當(dāng)你和其他人在同一時(shí)間克隆,他們先推送到上游然后你再推送到上游,你的推送就會(huì)毫無(wú)疑問(wèn)地被拒絕. 你必須先將他們的工作拉取下來(lái)并將其合并進(jìn)你的工作后才能推送. 閱讀 Git 分支 了解如何推送到遠(yuǎn)程倉(cāng)庫(kù)服務(wù)器的詳細(xì)信息.
?
?
git tag
git tag -l 'v1.8.5*'
git tag -a v1.4 -m 'my version 1.4' 附注標(biāo)簽
git tag -a v1.2 9fceb02 后期打標(biāo)簽
git tag v1.4 輕量標(biāo)簽
git show v1.4
?
git push origin v1.5 共享標(biāo)簽
git push origin --tags
git push origin --delete serverfix 刪除一個(gè)遠(yuǎn)程分支
基本上這個(gè)命令做的只是從服務(wù)器上移除這個(gè)指針. Git 服務(wù)器通常會(huì)保留數(shù)據(jù)一段時(shí)間直到垃圾回收運(yùn)行,所以如果不小心刪除掉了,通常是很容易恢復(fù)的.
?
?
git checkout -b version2 v2.0.0
在 Git 中你并不能真的檢出一個(gè)標(biāo)簽,因?yàn)樗鼈儾⒉荒芟穹种б粯觼?lái)回移動(dòng). 如果你想要工作目錄與倉(cāng)庫(kù)中特定的標(biāo)簽版本完全一樣,可以使用 git checkout -b [branchname] [tagname] 在特定的標(biāo)簽上創(chuàng)建一個(gè)新分支:
?
git checkout -b [branch] [remotename]/[branch]
git checkout --track origin/serverfix
git checkout -b sf origin/serverfix
?
git branch -u origin/serverfix
設(shè)置已有的本地分支跟蹤一個(gè)剛剛拉取下來(lái)的遠(yuǎn)程分支,或者想要修改正在跟蹤的上游分支,你可以在任意時(shí)間使用 -u 或 --set-upstream-to 選項(xiàng)運(yùn)行 git branch 來(lái)顯式地設(shè)置.
?
git branch
git branch -v 查看每一個(gè)分支的最后一次提交
git branch -vv 查看設(shè)置的所有跟蹤分支,可以使用 git branch 的 -vv 選項(xiàng)
需要重點(diǎn)注意的一點(diǎn)是這些數(shù)字的值來(lái)自于你從每個(gè)服務(wù)器上最后一次抓取的數(shù)據(jù). 這個(gè)命令并沒(méi)有連接服務(wù)器,它只會(huì)告訴你關(guān)于本地緩存的服務(wù)器數(shù)據(jù). 如果想要統(tǒng)計(jì)最新的領(lǐng)先與落后數(shù)字,需要在運(yùn)行此命令前抓取所有的遠(yuǎn)程倉(cāng)庫(kù). 可以像這樣做:$ git fetch --all; git branch -vv
git branch --merged
git branch --no-merged
?
git branch testing
git branch -d iss53
git checkout testing
git checkout -b iss53
?
git pull
a. 在大多數(shù)情況下它的含義是一個(gè) git fetch 緊接著一個(gè) git merge 命令.
b. 不管它是顯式地設(shè)置還是通過(guò) clone 或 checkout 命令為你創(chuàng)建的,git pull 都會(huì)查找當(dāng)前分支所跟蹤的服務(wù)器與分支,從服務(wù)器上抓取數(shù)據(jù)然后嘗試合并入那個(gè)遠(yuǎn)程分支.
git pull <遠(yuǎn)程主機(jī)名> <遠(yuǎn)程分支名>:<本地分支名>
?
git merge iss53
?
git rebase master
?
git gc
最妙之處是你可以隨時(shí)重新打包. Git 時(shí)常會(huì)自動(dòng)對(duì)倉(cāng)庫(kù)進(jìn)行重新打包以節(jié)省空間.當(dāng)然你也可以隨時(shí)手動(dòng)執(zhí)行 git gc 命令來(lái)這么做.
當(dāng)版本庫(kù)中有太多的松散對(duì)象,或者你手動(dòng)執(zhí)行 git gc 命令,或者你向遠(yuǎn)程服務(wù)器執(zhí)行推送時(shí),Git 都會(huì)這樣做.
Git 常見(jiàn)變量
HEAD: 表示最近一次的 commit.
MERGE_HEAD: 如果是 merge 產(chǎn)生的 commit,那么它表示除 HEAD 之外的另一個(gè)父母分支.
FETCH_HEAD: 使用 git-fetch 獲得的 object 和 ref 的信息都存儲(chǔ)在這里,這些信息是為日后 git-merge 準(zhǔn)備的.
HEAD^: 表示 HEAD 父母的信息
HEAD^^: 表示 HEAD 父母的父母的信息
HEAD~4: 表示 HEAD 上溯四代的信息
HEAD^1: 表示 HEAD 的第一個(gè)父母的信息
HEAD^2: 表示 HEAD 的第二個(gè)父母的信息
COMMIT_EDITMSG: 最后一次 commit 時(shí)的提交信息.
?
歡迎參與《LINUX學(xué)習(xí):Git部署與常用基本命令詳解》討論,分享您的想法,維易PHP學(xué)院為您提供專業(yè)教程。
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.snjht.com/jiaocheng/11324.html