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