Project Description

【分享實錄】git很流行,但你未必真懂!

華為大廠來了!碼農基地火了!

7月18日晚上8點,來自華為的美女程序媛潘靜做客碼農基地,分享了自己對git工具的認識和理解。這并不是碼農基地首次邀請女程序員前來分享,但是當晚的人氣還是讓我們大吃一驚,1900多名程序員參與了線上活動!碼農基地負責人熱淚盈眶地說,今后還是要想辦法多邀請女程序員來做分享!

閑話少說,下面奉上當晚分享活動的文字實錄:

大家好,我是潘靜,今天很高興和大家一起交流關于GIT工具的原理和使用,希望對大家有所幫助。

20180124111340

在講解GIT之前,我們先聊聊版本控制系統。在一個研發團隊中,最核心的產物就是代碼,它在開發的過程中越來越多,不斷地增長,如何去存儲、追蹤這些文件或者是目錄的變化,避免文件丟失或者是相互間的覆蓋,主要靠的就是版本控制系統。

版本控制系統主要分為兩類,集中式和分布式。集中式版本控制的特點是只有一臺中央服務器,它存放著所有的數據,包括代碼和提交記錄。而其他客戶端機器上,保存的是中央服務器最新版本的快照,它不包括那些logo,所以開發人員想工作的話,它必須要聯網。

20180124111853

分布式版本控制系統的特點是,每臺PC上都是代碼倉庫的完整鏡像,它沒有所謂的中央服務器和客戶端之說。但是有人可能會問,我們公司用的也是GIT,那為什么也有中央服務器???大家也會說,把代碼傳到服務器上。其實這個所謂的服務器,僅僅是為了約定大家多人寫作,是人為指定的,它和其它的機器本質上是相同的,任何一臺客戶端機器,都可以勝任這份工作。

集中式和分布式版本控制系統各有優缺點。對集中式版本控制系統來說,它的操作比較簡單,使用沒有難度,可以輕松地上手,并且對客戶端機器的配置要求不高,因為它不用存儲整套的代碼。當然缺點也是顯而易見的,中央服務器如果單點產生故障的話,整個服務器宕機,所有人都沒有辦法工作了。并且在沒有備份的情況下,磁盤一旦被損壞,所有的數據都將丟失。

分布式版本控制系統的優點是,版本庫是本地化的,包括所有的標簽、分支、版本記錄等等,它更適合的是一個跨地域的協同開發。它的缺點當然也可以看出,它學習成本比較高,不容易上手,只能針對整個倉庫去創建分支,沒有辦法更細地根據一個文件夾去創建分支。

集中式版本控制系統常見的有CVS、VSS、SVN、ClearCase等,而分布式版本控制系統一般有GitHub、Mercurial 和 Bazaar。這兩類中比較有代表性的就是SVN和GIT,他們兩個都有一個比較好的使用群體,優缺點也經常被比較,但在現在敏捷開發已經成為主流、迭代交互越來越快的情況下,我覺得GIT的趨勢越來越好,被越來越多的人所使用。

GIT誕生于2002年,由linux之父和他的團隊開發并不斷完善,它秉承了linux的開源精神,為我們開發團隊帶來了一個非常棒的而且完全免費的版本控制體驗。

20180124112124

在上圖中可以看到GIT的工作模式,一次代碼被成功地提交到遠端的倉庫,要經歷四個階段:本地工作區、暫存區、版本庫和遠端版本庫,文件在這四個狀態中是不同的。

在本地工作區包括三個類型的文件,新增文件、被修改的文件和被刪除的文件,如果你用GIT ?STATUS命令去查看的話,可以看到有兩種類型,一種是untracked files,它表示的是未被跟蹤的文件,一般指的是你新添加的文件;還有一種是Changes not staged for commit,這種類型的文件一般包括的就是?modified和deleted。

對已經修改的文件,我們進行GIT add或者GIT REMOVE操作的話,文件就到了暫存區。暫存區其實就是一個文件索引的目錄樹,它記錄了所有的文件名、文件狀態信息。如果把暫存區的文件,進行commit提交操作的話,文件就到了本地的版本倉庫,這時候如果再進行git push操作的話,就會把本端版本庫的內容push到遠端版本倉庫,完成了一次版本庫的提交。

20180124112207

讓我們來思考一下,版本控制系統它應該如何來記錄每次提交呢?我覺得正常的思維肯定是記錄差異,也就是說記錄修改文件有什么不同。的確,大多數版本控制系統就是這么做的,比如我們熟悉的CVS、SVN啊,但是GIT卻不是這樣,它每次提交時,把全部的文件做了一個快照,并且保存了指向這個快照的一個索引。

這種保存其實有很多好處,比如說切換版本的時候,我直接引用指向目標版本的索引就行了,就不需要差異存儲的那樣,我還需要版本之間的merge,所以速度就會提升許多。下面我將講到的輕量級的分支切換,就是因為這個原理。

20180124112245

GIT倉庫的默認分支是master分支,分支的本質是一個指向commit的指針,它會隨著每次提交不停地向前移動。而git創建一個分支的本質就是創建一個指向最后一次提交的可變指針,所以git分支的創建不是復制整個版本庫的內容,僅僅是新建了一個指針,它以40個字符長的長度保存在文件里,這是一個幾乎令人難以想象的輕量級。

20180124112318

如何去識別當前的分支是在哪里呢?這個就需要head指針來識別,就像上圖所示的那樣,分支切換前head指針指向的是master,當前的分支就是master,切換之后,head指針指向的是testing,當前的分支就是testing分支。

有分支的存在就必然會存在分支合并的情況,并且我們日常使用中出現的問題,一般也是分支合并引起的問題。無論哪種工作流,都會涉及到分支合并。它就是說把一個分支的修改整合到當前分支,一般有兩種方法,一種是merge,一種是rebase。

這兩種方法經常讓我們使用的非常不順手,或者是有一些誤區。我們現在就通過對一種場景進行不同的操作產生的兩種效果,來看這兩種方法的區別。

20180124112347

上圖中的場景是master分支上新增了一個C4的節點,hotfix分支上新增了一個C3的節點,我們要將hotfix分支合并到master分支上,什么時候容易有這種情況呢?通常是我們生產環境上出現了一個問題,需要拉出一個hotfix分支,然后解決以后,合入到master分支或者是develop分支,會有這種情況。

Merge的結果從log上看,它包括hotfix的新增節點C3,master的新增節點C4,以及兩者的共同祖先節點C2,這種合并操作非常簡單,但是有了一個新增的節點C5,它使整個合并的log上形成了一個環形,所以版本的可讀性非常差。

而rebase的操作呢,它先將master分支新增的節點C4,以補丁的形式保存在.git rebase這個目錄下,然后再去同步hotfix分支的最新代碼,最終再將這個補丁C4 ’去應用到這個分支上,這種log看上去非常地清晰。

20180124112421

有合并就會有沖突,一般沒有沖突的地方,系統會自動將他們合并到一起。而有一些沖突是需要我們手動來解決的。一般有兩種沖突,第一種就是說兩個合并分支它修改了同一行代碼,這種沖突會在整個文件中以這種尖括號、等號的形式將它括起來。

就如上圖中可以看到的,head所指的那一部分,等號和左尖括號中間的那一部分,指的是當前分支修改的內容,而等號下面的那一部分,是原分支的修改的內容,一般這些需要你人為地去確認,哪一些代碼需要留下來,哪一些代碼需要刪掉,人為地解決之后,然后再把這個代碼去提交。

20180124112452

還有一種類型的沖突,是文件被重命名為不同的名字,這種我們需要去確認哪一個名字是正確的,然后把錯誤的名字去刪除,再提交修改。

主持人:感謝老師精彩的分享,下面進入第二環節,老師答疑部分,有問題的伙伴直接把問題打在討論區即可,最后會根據優質問題,選擇三位伙伴分別獲得《代碼不朽》書籍一本。

靜待日出:git與svn的區別有啥呢?

潘靜:git和svn作為分布式與集中式的代表,他們本質上是工作模式的不同。Git本地有一套整個的代碼倉庫,離線也可以工作和查看log,而svn必須聯網。然后二者在安全性能上也是有不同的,git是一個分布式的系統,它每個用戶相當于對版本倉庫的一個備份,通過hash保證了數據的完整性,防止其他人的惡意篡改。而svn容易發生單點的故障,服務器端歷史數據如果被篡改的話,客戶端很難去發現。

榮信:我現在用的是svn,想遷移到git,成本高么?

潘靜:svn轉到git的遷移成本并不高,因為git有一個git svn clone的命令,可以把整個服務器遷移,后面加上服務器的URL填上就可以遷移過來了,但是遷移過之后可能涉及到一個git學習成本的問題,和一個使用習慣的問題。

康:使用git的時候一般常用工作流有哪些?

潘靜:git有幾個工作流。工作流也可以說是一個分支策略。第一個有一個集中式工作流,集中式工作流比較適合剛從svn遷移到git的使用群體。因為它一般只使用一個master分支,類似于svn上的trunk,可以做一個svn向git的過渡。它的特點是只有一個master分支,每個開發人員都要在這個分支的基礎上拉取一個最新的代碼,然后有沖突的話,rebase之后,然后再提交。

還有的就是功能分支的工作流。它的思路就是你每個功能都要單拉出來一個分支,在這個分支上去做功能的開發,然后再提交到master。

還有一個比較好的工作流,就是git flow工作流,它適用于一個大型的項目。它會有幾個分支,有兩個長期分支,分別是master分支和develop分支。Master分支版本的穩定性較強,一般是供生產環境的部署使用,這個分支一般只從其他分支上合并代碼,而不能從這個分支去直接提交。而develop分支是一個主開發分支,它用來集成、測試一些最新的開發成果,包含發布到下一個release的代碼。

還有一些短期分支,就是開發人員本地的一個feture分支,我要做一個特性開發,我就拉取一個feture,然后整個自己本地測試完成之后,合到develop。

芒果泥:請問學習git需要安裝什么客戶端?

潘靜:一般喜歡使用圖形化界面的,建議你安裝TortoiseGit、SourceTree、git cola或者是EGit,如果比較習慣使用命令的話,可以直接在git base的終端敲入命令行就行了。

星晨:fetch+rebase和pull本質區別是什么?

潘靜:git pull等于git fetch加git merge,而您說的fetch+rebase它就相當于merge和rebase的區別了。

站在倫敦橋上看船:我在鋪上的時候和別人沖突的,push失敗了。接下來什么操作可以解決這個問題?

潘靜:首先需要看您這個push失敗的原因是什么,如果是您本地沒有更新最新的代碼而導致的倉庫push不成功,那首先要pull一下,把最新代碼拉到本地再修改。如果是因為您和遠端的倉庫修改了相同的代碼行,導致了一個沖突,那就需要手動地去修改。

逄新利:git可以從某個文件夾創建分支嗎?

潘靜:git只可以針對整個代碼倉庫創建分支,它不能基于某個文件進行分支創建。

主持人:好的,感謝潘靜老師分享答疑,由于時間關系,伙伴們沒有回答的問題,稍后加群,老師也會在,大家可以繼續提問。恭喜康、星晨、榮信三位獲獎者,請聯系主持人并提供聯系地址,以便我們發放獎品。

本期活動由碼農基地主辦,WeX5移動開發云和華為聯合主辦。感謝老師今晚精彩的分享,感謝大家積極參與,感謝各位合作伙伴的支持!

20180124112525

index-icon-weibo index-icon-facebook index-icon-twitter github-1
wen-xin-2
? ??友情鏈接? ??| ? ??法律說明? ? ? ? ? 北京起步科技股份有限公司 ??2006-2017 ? ? ? ?京ICP備13007148號