《走进git时代系列一》 你该怎么玩?
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                《走进git时代系列一》 你该怎么玩?
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                首先,這篇分享不是git命令操作大全,不是某代碼托管服務(wù)的硬廣, 只是希望激發(fā)仍然在使用中世紀(jì)時期版本管理系統(tǒng)的同學(xué)們,能夠放棄你手里的SVN,轉(zhuǎn)向更先進(jìn)的思路。
所以,大家不會看到非常多的Command Line 教你Step By Step Git init :) , 請放心像讀故事一樣,慢慢理解為什么要擁抱Git,以及玩轉(zhuǎn)Git你需要做什么?
本文大概分為以下幾個篇章:
版本管理的發(fā)展歷史
- 什么是版本管理, 當(dāng)你在兒童時期玩游戲的時候,在打Boss之前的存檔, 就是最原始版本管理的目的。
 - 那么我們先來看看版本管理的歷史, 我想引用coolshell.cn里的一些內(nèi)容,先來看從網(wǎng)上找到的一張版本管理時代變遷圖 :
 
- 這張圖上分成了四個時期:
 - 史前時期:1982年的RCS。現(xiàn)在你可能還能在Unix的發(fā)布包中找到它。
 - 古典時期:1990年的CVS,1985年的PVCS,1992年的clearcase(價格貴,功能復(fù)雜,當(dāng)然,今天還有人在用),微軟的VSS(Welcome to Hell),90年代中期的Perforce(P4,這個工具今天都還在被廣泛地使用,尤其是那些中等大小卻有著大量開發(fā)團(tuán)隊(duì)的公司,現(xiàn)在是Google內(nèi)部最大的代碼管理器)。
 - 中世紀(jì)時期:SVN,AccuRev(強(qiáng)力支持branch和merge,其扮演了一個很重要角色幫助社區(qū)脫離clearcase和CVS),
 - 文藝復(fù)興時期:BitKeeper——Sun的內(nèi)部管理工具,Linux的內(nèi)核代碼2002年也用這個工具,其實(shí),很多開源工程都在用這個工具,2005年這個工具的東家BitMover對大家對BitKeeper逆向工程很不滿,于是停止支持開源,于是出現(xiàn)了Git。
 - Git 誕生于一個極富紛爭大舉創(chuàng)新的年代。可以看到同期出現(xiàn)了其他不少創(chuàng)新的版本管理系統(tǒng):
 - Mercurial (Hg) 第一次出現(xiàn)在2005年4月,也是因?yàn)锽itKeeper不免費(fèi)了。Hg可以和Git在一起使用,見:HG_GIT 。但是Hg和Git在設(shè)計(jì)上不一樣,他們對提交/變更的概念是一樣的,只不過Git用tree來實(shí)現(xiàn),而Hg則是用扁平的文件和目錄來實(shí)現(xiàn)(revlog)
 - Darcs (Darcs Advanced Revision Control System)是另一個讓你擺脫Subversion和CVS的工具,2002年開始,今年是2.5版。它的優(yōu)勢是性能,以及他與眾不同的歷史版本管理——管理patches而不是snapshot(提交/修改),當(dāng)然,這樣一來,歷史改變看上去很不好懂。
 - Bazaar (bzr) 是另一個開源的 DVCS,它試圖給SCM的世界里帶來一些新的東西。其由Canonical開發(fā)(Ubuntu的那個公司),在2008年成為GNU。
 - Plastic在2006年出現(xiàn),強(qiáng)力地支持branch和merge,其還提供了強(qiáng)大的圖示,包括3D的版本樹,Plastic主要是為了讓中等開發(fā)團(tuán)隊(duì)使用,介于大型的團(tuán)隊(duì)(ClearCase)和小型的團(tuán)隊(duì)(Subversion)之間。
 - Team Foundation Server (TFS),微軟的新一代SCM工具,主要是為了VSS的失敗負(fù)責(zé),但是他還不是版本管理上還是很強(qiáng),只不過,他集成了一大堆各種各樣的工具,比如:issue tracking,test management等。
 
為什么Git能如此的火爆
- 我認(rèn)為:首先,Git 很牛逼, 然后,基于Git的產(chǎn)品很牛逼 。
 - Git 產(chǎn)生的背景相信大家或多或少都聽過,Linux 內(nèi)核開源項(xiàng)目在全世界有無數(shù)人在參與,因?yàn)槿颂嗔?#xff0c;所以他們在1991~2002年間絕大多數(shù)的維護(hù)工作都花在了提交補(bǔ)丁和保存歸檔的繁瑣事務(wù)上。 到 2002 年,整個項(xiàng)目組開始啟用一個專有的分布式版本控制系統(tǒng) BitKeeper 來管理和維護(hù)代碼。
 -  
到了 2005 年,開發(fā) BitKeeper 的公司和 Linux 內(nèi)核開源社區(qū)解除了合作關(guān)系,不免費(fèi)給他們用了。 基于和BitKeeper的殘酷經(jīng)驗(yàn), 逼迫他們必須自己開發(fā)一個版本管理系統(tǒng), 于是按照下面幾個要求開始:
- 速度
 - 簡單的設(shè)計(jì)
 - 對非線性開發(fā)模式的強(qiáng)力支持(允許成千上萬個并行開發(fā)的分支)
 - 完全分布式
 - 有能力高效管理類似 Linux 內(nèi)核一樣的超大規(guī)模項(xiàng)目(速度和數(shù)據(jù)量)
 
 
- Git的第一個版本是Linux之父Linus Torvalds親手操刀設(shè)計(jì)和實(shí)現(xiàn)的(據(jù)說只用了一個周末),Linus不僅僅給出一個原始設(shè)計(jì)(簡單的、干凈的、天才的),同時,他也用自己那獨(dú)一無二的風(fēng)格催生了這個項(xiàng)目(請參看: http://codicesoftware.blogspot.com/2007/05/linus-torvalds-on-git-and-scm.html 還是被墻)。
 - 在Linus介紹Git的著名的演講中,他強(qiáng)烈地批評(應(yīng)該算是侮辱)了CVS,SVN,和Perforce:“Subversion是史上最毫無意義的項(xiàng)目,從項(xiàng)目開始就是這樣了”,“如果你喜歡CVS,那么你現(xiàn)在應(yīng)該在某個精神病研究中心或是別的地方”,“別在用Preforce了,它是十分糟糕和可悲的,這絕對絕對是真的”。無論是反對還是喜歡,Linus的確是改變了歷史——中世紀(jì)已經(jīng)過去了,現(xiàn)在的世界由分布式系統(tǒng)主宰,以及消除branch和merge的恐懼。
 - Git 基于 DAG 結(jié)構(gòu) (Directed Acyclic Graph),其運(yùn)行起來相當(dāng)?shù)目臁T贕it發(fā)布后的來年,世界上所有的大型的開源項(xiàng)目全部從Subversion遷移到了Git上。
 - 為什么說基于Git的產(chǎn)品很牛逼, 因?yàn)镚ithub真是很大,從Linux內(nèi)核遷移到Github 上開始,經(jīng)歷了七八年到現(xiàn)在,已經(jīng)成為全世界公認(rèn)的開源代碼,開源社區(qū)的地方。 無數(shù)程序員們都是先知道Github, 才知道Git。所以,學(xué)習(xí)Git, 網(wǎng)絡(luò)上無數(shù)的命令大全,上手指南,高階學(xué)習(xí)的帖子無處不在。
 - 所以,Git可能并不是最簡單的,但它已經(jīng)是現(xiàn)在的主流.
 
不要用SVN去思考Git
- 說完上面那么多的歷史,我不想再費(fèi)力氣說明為什么Git 優(yōu)與SVN了, 什么因?yàn)槭荂寫的所以運(yùn)行更快我,因?yàn)槭欠植际降谋戎行幕酶奖?#xff0c; 元數(shù)據(jù)方式存儲比文件存儲更優(yōu)等等, 因?yàn)镾VN,已經(jīng)是上一個時代的產(chǎn)物了。
 - 那么, 這個章節(jié)想要說明的是,不要用SVN的思想和操作方式 去理解Git 。
 - 首先, Git 到底是什么? 很多人說,git是分布式,git本質(zhì)是一個 key/value 的文件管理系統(tǒng),git是對blob二進(jìn)制數(shù)據(jù), tree最好的解釋。
 - 我個人最認(rèn)可對git的理解是: git is a directory content, management system, tree history, storage system , stupid content tracker and a toolkit
 - Git 和 SVN 思想最大的差別有四個:
 
去中心卻集中(Decentralized but centralized)
- 我們都知道Git是一個DVCS(分布式版本管理系統(tǒng)),在技術(shù)層面上并不存在一個像中心倉庫這樣的東西 , 所有的數(shù)據(jù)都在本地,不存在誰是中心,大家每個人本地都一樣, 但我們?nèi)匀恍枰獏f(xié)作,Git 同樣有Server的概念, 在下圖中,origin 是我們熟知的名詞,這個中心是誰,就取決于你用什么代碼托管系統(tǒng)了。 你可以在公司本地服務(wù)器搭建Git Server, 當(dāng)然我更推薦使用阿里的產(chǎn)品code.aliyun.com
 
- 每個開發(fā)者拉取(pull)并推送(push)到origin。但除了這種集中式的推送拉取關(guān)系,每個開發(fā)者也可能會從其他的開發(fā)者處拉取代碼的變更,從而形成一個子團(tuán)隊(duì)。例如,當(dāng)與兩個或更多的開發(fā)者協(xié)同工作于一個大的新特性時,在將工作代碼推送到持久的origin之前,這可能很有用。在上圖中,Alice和Bob,Alice和David,以及Clair和David,分別構(gòu)成了子團(tuán)隊(duì)。
 - 從技術(shù)上講,這只不過意味著Alice定義了一個名為bob的Git的remote,它指向了Bob的軟件倉庫。反之亦然。
 
直接記錄快照,而非差異
- Git 第二個思想也是和SVN最大的差異化,即每一個版本都是直接記錄快照,而非文件的差異。 下面兩個對比圖在網(wǎng)上是廣為流傳大家應(yīng)該熟悉:
 - SVN :
 
- Git:
 
!
- GIT 使用SHA-1算法計(jì)算數(shù)據(jù)的校驗(yàn)和 ,通過文件的內(nèi)容或目錄計(jì)算出SHA-1哈希值,作為指紋字符串, 每個Version 都是一個快照。 所以Git的最小概念是倉庫,SVN的最小概念是文件。
 
不一樣的分支概念
- 因?yàn)椴皇怯涗浳募町?#xff0c;Git的分支本質(zhì)是一個指向提交快照的指針,是從某個提交快照往回看的歷史。
 - 當(dāng)創(chuàng)建/切換分支的時候,只是變換了指針指向而已,所以會發(fā)現(xiàn)創(chuàng)建分支非常的快,同樣當(dāng)git init 之后就會有一個默認(rèn)的分支, 我們通常叫master ,但這實(shí)際上不是主干,沒有所謂的主干和分支的差別, master只是命名為master的一個分支, 是我們?yōu)榱税姹竟芾淼牧?xí)慣叫法而已。 ,
 - SVN創(chuàng)建一個分支, 是的的確確的復(fù)制了一份文件, 而如剛才說SVN的每一次Version 是記錄了文件差異, 因此假入你commit了一個1M的文件到SVN服務(wù)器, SVN Server的存儲增加了1M,當(dāng)你刪除了這個1M大小的文件并Commit的時候,SVN Server的存儲又增加了1M。 所以,你是不會想知道像BAT這三家公司內(nèi)部的SVN Server今天占用了多大存儲空間的-。-
 
三個工作區(qū),三個文件狀態(tài)
-  
在 Git 中,存在三個工作區(qū)域:
- 工作目錄
 - 暫存區(qū)域
 - 本地倉庫
 
 -  
同時,文件有三種狀態(tài):
- 已提交(committed):該文件被安全地保存在了本地?cái)?shù)據(jù)庫
 - 已修改(modified):修改了某個文件,但還沒有保存
 - 已暫存(staged):把已修改的文件放下下次保存的清單中
 
 - 下圖說明了這三個區(qū)域和文件狀態(tài)的差別:
 
- 所以,在Git中,你可以暫存部分文件,甚至一個文件中的部分內(nèi)容,你的本地可以將版本管理玩的非常復(fù)雜和有趣。 這也是為什么 SVN 用戶最常疑問 Git 為什么每次都要TM的 git add 才能再 commit 的原因
 
玩轉(zhuǎn)Git 與協(xié)作
- Git 常用的命令這里不解釋了, 但是我們都是在公司內(nèi)的程序員,即便是個人開發(fā)者也會有在社區(qū)的伙伴們,所以代碼管理一定要有協(xié)作的部分, 你一定不是一個人在戰(zhàn)斗。
 - 因此我個人的理解,什么是一個好的代碼庫管理:庫不大, 分支少,tag多, 分支或CI log 和Issue關(guān)聯(lián),分支開發(fā)master發(fā)布, 小步迭代, 版本樹清晰漂亮,功能分支永遠(yuǎn)和Master離的很近, 所有開發(fā)熟悉rebase和遵循Merge request習(xí)慣
 - 話有點(diǎn)糙,實(shí)際上就是敏捷開發(fā)中的一部分概念, 即便一定要拉出功能分支,也一定要快速合并,否則不如變成兩個代碼庫,兩個應(yīng)用。
 - 所以玩轉(zhuǎn)git協(xié)作, merge,rebase和cherry-pick是你一定要理解的三個概念。
 - 首先, Merge , 合并代碼,人人都能理解, 在Git中存在 fast forward 和no fast fast forward branch merging , 并沒有好壞之分, 差別在于,fast forward 實(shí)際上不會產(chǎn)生代碼合并, 比如你改了a文件,我改了b文件,這兩個分支Commit的文件不存在任何的合并, 所以可以進(jìn)行ff merge,從而使版本樹是一條線; 而產(chǎn)生了merge 之后的版本樹會有多一個merge節(jié)點(diǎn)產(chǎn)生, 版本樹是兩條線合并到一條線。
 - Rebase 和 Cherry-pick 這里要多講兩句了 ~
 
cherry-pick
- cherry-pick的對象可以是分支也可以是一個commit.
 
- 當(dāng)我執(zhí)行 git cherry-pick <commit id of F> , 就會把分支上的F拿過來,變成下面的效果:
 
- cherry-pick可以自動生成commit,這時候本分支上會有一個新的commit id,但是提交內(nèi)容 F’=F。你再本分支上看到的log將是賞心悅目的直線。
 - 如果cherry-pick的是一個分支呢?同樣的例子,git cherry-pick <branch name>會將另一分支上的每個提交按順序加到本地,如果有沖突會提醒,解決沖突后提交即可。
 
rebase
- 從字面上理解是復(fù)位基底,也是很形象的。它大概的意思如下:
 
- 詳細(xì)的解釋和用法推薦看: http://gitbook.liuhui998.com/4_2.html
 
因此:
- cherry-pick和rebase的區(qū)別是,一個是把別人的拿來,別人的提交會在HEAD上加入。rebase是把自己的根本切換,別人的提交會在自己的尾部。
 - cherry-pick和rebase的好處是log簡潔,是一條直線。適用于自己本地的分支管理,讓自己的提交盡量是一條直線。
 - merge會產(chǎn)生一次提交,適用場景是多人合作的場景,不同或者同一分支開發(fā)時。會產(chǎn)生有交點(diǎn)的多條線, 除非是ff的merge。
 
學(xué)習(xí)Git的一些參考資料
- 推薦一堆沒用, 其實(shí)學(xué)習(xí)Git, 就兩本書足以成為使用上面的專家。 Pro Git 簡體中文版 ,這個上手可以。 還有一本 《Git權(quán)威指南》 這個可以作為工具書了,因?yàn)槔锩嬷v的比較深,講到了Git 一些底層命令(類似git rev-parse , git ls-tree 這種), 如果你是SCM 或者公司內(nèi)的版本管理者,是需要有這本書的。
 - 另外如果你是linux 或者 mac 用戶, 命令行將是Git 最好的伙伴。 如果是Windows ,也建議直接用 Git bash 來進(jìn)行操作。
 - 不過,如果為了使用更加的方便, 建議裝SourceTree 或者 Github 客戶端 這兩個客戶端工具, 不要裝小烏龜?shù)腉it版本了。
 
寫在最后
- 當(dāng)然 , Git 和SVN的思想差異, Git 中需要學(xué)習(xí)的地方很多, 上面提到的都只是我個人認(rèn)為比較重要的點(diǎn)而已。 希望這篇文章能讓大家從SVN等其他版本管理工具中遷移到Git上來。
 - 針對SVN遷移GIT , 我們推出了《走進(jìn)git時代系列二》 從SVN遷移到GIT教程 https://yq.aliyun.com/articles/6046
 - 以及《玩轉(zhuǎn)云Code最佳實(shí)踐》 ,會講在 https://code.aliyun.com 上進(jìn)行代碼協(xié)作的最佳實(shí)踐 。
 - 以及 《云上持續(xù)交付最佳實(shí)踐》, 會包含如何使用https://crp.aliyun.com 及阿里云Docker 容器服務(wù) 如何進(jìn)行持續(xù)集成,到持續(xù)交付的實(shí)踐教程, 敬請期待。
 
總結(jié)
以上是生活随笔為你收集整理的《走进git时代系列一》 你该怎么玩?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: git常用命令(二)
 - 下一篇: LeetCode - 28. Imple