30分鐘教你輕松使用Git做代碼管理

30分鐘教你輕松使用Git做代碼管理

2017-06-20

Git的起源

(故事性內(nèi)容,不喜跳過,干貨往下看)

git的由來說白了,就是一個(gè)天才程序員,因?yàn)椴幌矚g傳統(tǒng)的代碼版本控制工具(集中式)或者喜歡的工具不開源,就自己花了半個(gè)月的時(shí)間寫了這么一個(gè)流行至今的“分布式版本控制系統(tǒng)”。

當(dāng)年,Linux的發(fā)明人Linus Torvalds將Linux的源碼放置開源社區(qū)后,開始接收來自世界各地的志愿者們貢獻(xiàn)的代碼,并手工合并??上攵?,隨著linux社區(qū)日益活躍,Linux的源碼也更加龐大,這樣的手工合并代碼的方式越來越困難,也越來越不像程序員的做事風(fēng)格。

不是早就存在像SVN和CVS這樣的自動(dòng)化代碼版本控制工具嗎?然而Linus表示,堅(jiān)決抵制集中式版本控制器。因?yàn)榧惺降墓ぞ卟坏俣嚷?,而且如果中央服?wù)器突然宕機(jī),或者沒有網(wǎng)絡(luò),團(tuán)隊(duì)幾乎無法提交工作。那Bitkeeper這樣強(qiáng)大的分布式版本控制工具呢?事實(shí)上,從2002年開始,linus就開始用Bitkeeper管理代碼,自此,Linux的發(fā)展步伐加快了一倍。

然而,Bitkeeper是一款商業(yè)版軟件,雖然為開發(fā)開源軟件的兄弟們提供使用許可,但是同時(shí)也限制開源社區(qū)不可以開發(fā)具備相同功能的軟件。但程序員們哪有幾個(gè)是安份的?開源社區(qū)的兄弟們更是如此。Linux和Bitkeeper交往的大好時(shí)光持續(xù)到2005年,開發(fā)Samba的Andrew試圖破解BitKeeper的協(xié)議,卻被Bitmover公司(Bitkeeper的研發(fā)公司)發(fā)現(xiàn)了,從此收回了在開源社區(qū)使用Bitkeeper的許可。

激動(dòng)人心的時(shí)刻來了,Linus和Bitmover公司的CEO Larry McVoy是好朋友,本來可以為社區(qū)的兄弟們低個(gè)頭,向Bitmover認(rèn)個(gè)錯(cuò),以前怎么哥倆好,今后繼續(xù)怎么搞。

但是天才就是天才,Linus隨后花了半個(gè)月的時(shí)間用C寫了一個(gè)分布式版本控制器,并在一個(gè)月內(nèi)將Linux的代碼完全由其托管,這個(gè)工具就是Git。當(dāng)然,開源的。

時(shí)至今日,Git已經(jīng)成為了最為流行的代碼管理工具。隨著Github網(wǎng)站的上線,更是紅得一發(fā)不可收拾。

Tips:據(jù)說去年,Bitkeeper也開源了。

Git vs SVN

上面說了這么多,無非是想表達(dá)的對(duì)天才程序員的敬佩之情和對(duì)開源精神的推崇,雖然自己還只是一個(gè)Coder,但也會(huì)努力成為一個(gè)厲害的Programmer的。

為什么Linus抵制像SVN這樣的集中式版本控制呢?Git是分布式的,和集中式的區(qū)別究竟在哪呢?我們接下來就來探討下。上圖

SVN開發(fā)流程

可以看出,所有的開發(fā)者都是通過連接中央服務(wù)器進(jìn)行代碼獲取或者代碼提交的。開發(fā)人員之間,必須通過中央服務(wù)器來合作開發(fā)。中央服務(wù)器中保存著完整的版本庫(kù),開發(fā)者如果要進(jìn)行版本控制,需要連接網(wǎng)絡(luò)。若服務(wù)器宕機(jī),或者網(wǎng)絡(luò)中斷,開發(fā)工作將無法開展。

git_work_flow
git_work_flow

而對(duì)于分布式的版本控制器,每個(gè)人的電腦上都可以保存一份完整的版本庫(kù)。從remote pull下來最新的代碼,如果網(wǎng)絡(luò)中斷,開發(fā)人員完全可以在本地做版本回滾和修改提交,再在聯(lián)網(wǎng)的時(shí)候推送到遠(yuǎn)程倉(cāng)庫(kù)。若兩名開發(fā)人員合作開發(fā)一個(gè)功能,可以不經(jīng)過遠(yuǎn)端服務(wù)器就可以相互之間推送修改,合并沖突后,再由某一人推送代碼。大大得提高了開發(fā)效率。而且如果服務(wù)器壞了,數(shù)據(jù)丟失,沒關(guān)系,每個(gè)人都有完整的版本庫(kù),從其他人那里clone一份就ok了。當(dāng)然,信息安全的問題也就來了。

當(dāng)然,對(duì)于一個(gè)項(xiàng)目的開發(fā),選擇集中式或者分布式的版本控制并不是關(guān)鍵問題,我認(rèn)為提高版本控制的決定因素在于良好的分支管理策略,這里還是比較講究的。有興趣的同學(xué)可以參考《Git權(quán)威指南》。

Git初體驗(yàn)

講了這么多,我們來實(shí)際演練下git的操作吧。由于習(xí)慣了命令行操作,雖然公司推薦小烏龜,但我還是很傲嬌的用git bash

環(huán)境搭建

  • window10(win7也ok,64bit或者32bit無關(guān)緊要,都有對(duì)應(yīng)的git版本)

  • git的win版官網(wǎng)下載地址 下載最新版的可以的。30M+,一會(huì)就下好了。

  • github遠(yuǎn)端倉(cāng)庫(kù),登陸官網(wǎng)注冊(cè),創(chuàng)建一個(gè)就好

安裝

看到以下畫面前一路next(注意設(shè)置安裝路徑)

git_install1
git_install1

然后按上圖進(jìn)行單選,接著一路next,安裝就好了。在新建一個(gè)文件夾,進(jìn)入,在空白處右擊,會(huì)發(fā)現(xiàn)右鍵菜單多了兩個(gè)選項(xiàng),Git GUI here,Git Bash here。選擇第二個(gè)。進(jìn)入如下界面

git_bash_gui
git_bash_gui

這個(gè)就是git的命令行界面了。

我利用git提交代碼的流程

git在window的安裝需要200M+的空間,而在Linux上安裝包卻非常小,很有可能是因?yàn)閣indows上啟動(dòng)git,首先會(huì)啟動(dòng)一個(gè)輕量級(jí)Linux系統(tǒng),然后再在其中啟動(dòng)git,你會(huì)發(fā)現(xiàn)在git bash界面上,你能夠使用很多Linux下的代碼,包括vim編輯器,有點(diǎn)小激動(dòng)。
Tips:C://Users/[你的用戶名]/目錄下面有一個(gè).bashrc文件,這個(gè)文件和Linux的.bashrc一樣,在啟動(dòng)時(shí)加載,配置bash的環(huán)境變量,你可以在這里配置java的環(huán)境變量,這樣就能在git bash使用java命令了。其他軟件也是如此。

假設(shè)你剛進(jìn)公司,公司在github上托管了一個(gè)開源項(xiàng)目(我剛剛創(chuàng)建一個(gè)空的項(xiàng)目),你需要在上面開發(fā),你首先需要從github上clone一份完整的最新代碼。復(fù)制下圖鏈接

git_clone_url
git_clone_url

然后在git bash敲入如下命令git clone [剛剛復(fù)制的鏈接],并進(jìn)入目錄。

git_clone_bash
git_clone_bash

查看code1.txt的內(nèi)容

code1_content_pre
code1_content_pre

你已經(jīng)或得了完整的代碼了,現(xiàn)在你可以嘗試進(jìn)行開發(fā)。一般這個(gè)時(shí)候,我會(huì)選擇新建一個(gè)分支,在那個(gè)分支上做開發(fā),完成后切換回主分支,合并新建的分支,再提交代碼。那什么是分支呢?參考這里吧!

敲入git checkout -b dev來新建一個(gè)名為dev的分支。

git_checkout_-b
git_checkout_-b

git checkout 這個(gè)命令是用來切換分支的,如果帶上了-b選項(xiàng),就表示新建一個(gè)分支。git branch是查看所有分支,分支名前帶分號(hào)的表示當(dāng)前所在分支。-a選項(xiàng)表示羅列所有分支,包括本地和遠(yuǎn)程追蹤分支。

**Tips: **在命令后設(shè)置-h可以查看命令幫助,--help可以啟動(dòng)瀏覽器查看更加詳細(xì)的幫助文檔。

好了,分支也建好了,我們可以嘗試開發(fā)了,我們做如下操作:

  1. 在code1.txt中修改第一行,并增加若干行。
  2. 新建一個(gè)文件,寫入一些內(nèi)容
code1_content_after1
code1_content_after1
mycode_create
mycode_create

你在項(xiàng)目中添加了新的文件,并且更改了舊的文件,可以通過git diff命令查看修改

git_diff
git_diff

你發(fā)現(xiàn),對(duì)于code1.txt中原本一行的修改,git簡(jiǎn)單粗暴的記錄為刪除后,再添加。對(duì)于新增的內(nèi)容記錄為增加。是的,git是以行(hang)為單位記錄文件的修改。等等,你發(fā)現(xiàn)我們剛剛新建的mycode1.txt文件并沒有被顯示。使用git status命令查看當(dāng)前工作空間狀態(tài)

git_status
git_status

mycode1.txt是Untracked files,這個(gè)文件未被git追蹤,你需要通過git add .將你的所有修改、新增、刪除添加進(jìn)工作區(qū)的暫存區(qū)stage,什么是git的暫存區(qū)呢,參考

敲入git add .

git_add
git_add

再用git status可以看到,能夠看到所有文件的修改了。mycode.txt為新增文件。

現(xiàn)在你完成了你的工作,準(zhǔn)備提交所有的修改,敲入git commit -m "一些信息"

git_commit
git_commit

將代碼的變化提交到本地倉(cāng)庫(kù)?,F(xiàn)在的分支是dev,我們切換回master

git_checkout_master
git_checkout_master

可以看出,切換回master分支后,你會(huì)發(fā)現(xiàn)目錄下只有code1.txt文件了,自己新建的文件不復(fù)存在。(注意:如果在dev分支上沒有commit修改,在master分支上能夠看到在dev分支上的修改。)

我們以圖來分析

git_branch_manage_pic1
git_branch_manage_pic1

這是最開始的狀態(tài),只有一個(gè)master分支,HEAD指向當(dāng)前分支的最新版本。

git_branch_manage_pic2
git_branch_manage_pic2

新建一個(gè)分支后,同時(shí)也切換到dev分支上,此時(shí)HEAD指向dev,master和dev的最新版本是一樣的。

git_branch_manage_pic3
git_branch_manage_pic3

現(xiàn)在在dev分支上修改,并提交代碼,你會(huì)發(fā)現(xiàn),dev開始和master分開了,

git_branch_manage_pic4
git_branch_manage_pic4

多次提交代碼后,切換回master,此時(shí)master的版本早已落后于dev,通過git merge dev命令將dev分支合并進(jìn)master分支中,以保證版本一致.

git_branch_manage_pic5
git_branch_manage_pic5
git_merge_dev
git_merge_dev

現(xiàn)在,你可以在將master分支推送的遠(yuǎn)端倉(cāng)庫(kù)的master分支了。

git_push_origin
git_push_origin

**Tips: **截圖中的命令很仔細(xì)的制定了本地分支和遠(yuǎn)程分支的名字git push origin [local branch]:[remote branch],事實(shí)上,如果使用了git branch --set-upstream [本地分支] [遠(yuǎn)程分支]關(guān)聯(lián)本地和遠(yuǎn)端分支后,可以直接簡(jiǎn)寫git push推送代碼。git branch -vv可以查看本地和遠(yuǎn)端分支的關(guān)聯(lián)。

git branch -D dev刪除dev分支

git_branch_-D
git_branch_-D

這大概是我每天最常的一套提交代碼的流程,只要沒有人碰我修改了的文件,就不會(huì)發(fā)生代碼沖突,一般能夠順利提交(后面會(huì)演示沖突的產(chǎn)生和解決辦法)。此外,你不會(huì)直接提交修改給遠(yuǎn)端master分支,一般會(huì)設(shè)置評(píng)審分支,日常的代碼先提交到評(píng)審分支,再發(fā)起合并請(qǐng)求,請(qǐng)相關(guān)大佬review代碼,再合并進(jìn)master分支。這個(gè)還是比較簡(jiǎn)單的分支管理策略,對(duì)于持續(xù)發(fā)布的項(xiàng)目,分支管理是更加復(fù)雜的。具體可以查閱阮一峰的博客,或者搜索“git flow”,"gitlab flow","github flow"關(guān)鍵字。

代碼沖突

在多人協(xié)作開發(fā)的情況下,代碼沖突是常有的事,每次辛辛苦苦地修改完bug,增加feature,滿心歡喜的推送代碼,等著下班回家陪媳婦,結(jié)果看到由于代碼沖突而導(dǎo)致merge失敗的錯(cuò)誤,真的有點(diǎn)想shi.

angry

親親抱抱舉高高,沒什么大不了。下面我就以我的經(jīng)驗(yàn),演示下沖突的產(chǎn)生,以及解決辦法。

情況1:研發(fā)A修改了code1.txt文件并合并到master,此時(shí)研發(fā)B修改了mycode1.txt文件,想要合并到master(A已經(jīng)合并)

devA_edit_code1
devA_edit_code1

在code1.txt中增加新內(nèi)容

git_merge_devA
git_merge_devA

提交修改,并切換回master分支,merge devA

devB_edit_mycode1
devB_edit_mycode1

checkout devB分支,修改mycode1.txt內(nèi)容

git_merge_devB
git_merge_devB

再提交修改,并切換回master,合并devB

合并成功,這是不會(huì)發(fā)生沖突的。因此,如果每個(gè)人修改的不同的代碼文件都,合并是不會(huì)發(fā)生沖突的。

情況2:研發(fā)A和研發(fā)B合作開發(fā)新功能,A修改了code1.txt文件并合并到master,此時(shí)B在他的分支上也修改了code1.txt文件,想要合并到master(A已經(jīng)合并)

devA_edit_code1_2
devA_edit_code1_2

修改完code1.txt后,devA提交修改,并切換到master,合并devA

devB_edit_code1
devB_edit_code1

切換到devB,由于沒有更新代碼,你發(fā)現(xiàn)devB分支上的code1.txt文件沒有devA之前修改的痕跡,同樣的,devA分支上的mycode1.txt也沒有devB的修改。修改code1.txt,增加一行內(nèi)容。

emerge_conflict
emerge_conflict

切換回master,進(jìn)行合并發(fā)現(xiàn)代碼沖突,合并失敗。此時(shí)右下角顯示merging狀態(tài)。激動(dòng)人心的時(shí)刻到了!

神秘的微笑
conflict_git_status
conflict_git_status

這個(gè)時(shí)候使用git status命令可以看到,code1.txt被同時(shí)修改了,所以產(chǎn)生沖突。繼續(xù)使用git diff命令查看code1.txt中的沖突

conflict_git_diff
conflict_git_diff

命令行中看到上面這樣的內(nèi)容,第一反應(yīng)是崩潰的,本能的就會(huì)抵制繼續(xù)往下看,而開始尋找好用的GUI工具。這就是人們對(duì)未知事物的本能反應(yīng),抗拒。其實(shí)讀懂這些符號(hào)就沒啥了。這些內(nèi)容是實(shí)實(shí)在在得寫在了文件中的,在實(shí)際的工程中,如果有實(shí)時(shí)編譯的IDE,立馬就會(huì)報(bào)錯(cuò)。我們用vim編輯code1.txt,以圖解決沖突。

conflict_solve1
conflict_solve1

第一部分是沖突中HEAD的修改,現(xiàn)在在master分支,自然是指master的修改。第二部分就是devB的修改。

conflict_solve2
conflict_solve2

簡(jiǎn)單粗暴的刪除git自動(dòng)添加的符號(hào),完成沖突解決。注意:實(shí)際開發(fā)中,沖突的解決還是的小心一點(diǎn),兩個(gè)人當(dāng)面核對(duì)代碼沖突還是很有必要的。如果不能見面溝通,最好是在理解對(duì)方的修改后,再解決沖突。否則弄丟了對(duì)方辛辛苦苦修改的代碼,還是很崩潰的。

conflict_git_merge
conflict_git_merge

之后將修改add進(jìn)暫存區(qū),然后commit。merge會(huì)自動(dòng)完成。git log可以查看版本歷史

一般在工程中,推送代碼前,重新從遠(yuǎn)端倉(cāng)庫(kù)pull一份新的代碼,和本地分支做合并,在本地解決沖突后,再推送到遠(yuǎn)程倉(cāng)庫(kù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 聲明:這篇文章來源于廖雪峰老師的官方網(wǎng)站,我僅僅是作為學(xué)習(xí)之用 Git簡(jiǎn)介 Git是什么? Git是目前世界上最先...
    橫渡閱讀 4,137評(píng)論 3 27
  • 轉(zhuǎn)載直:http://www.open-open.com/lib/view/open1414396787325.h...
    htzeng閱讀 438評(píng)論 0 2
  • 我兒子經(jīng)常說 我是凹凸曼,我要變身 5歲的孩子太幼稚了 其實(shí)我比他還小剛會(huì)走路 就擁有了變身的能力 只不過。。。。...
    e0c9b0c45626閱讀 275評(píng)論 0 4
  • 如果你的讀者從來都不看你新寫的文章,那可能說明他們是真的愛你。 我已經(jīng)忘記是從哪里看到上面這句話了,但每當(dāng)我寫的文...
    技匠閱讀 2,916評(píng)論 32 94
  • 我不喜歡剪不斷理還亂的關(guān)系 今天問了下他的態(tài)度,人家更多是覺得這幾年自己沒有開心,而我覺得我的付出沒有被珍惜。 既...
    郭文卓閱讀 402評(píng)論 0 0

友情鏈接更多精彩內(nèi)容