一行注釋代碼背后的故事
如果你打開騰訊地圖,查看網(wǎng)頁源碼,可以看到一行注釋:
<!--modified by nimomeng 添加統(tǒng)計(jì)額外參數(shù)opt,在此處設(shè)置其key為areaId,value為left-->
‘nomomeng’同學(xué)是一個(gè)前端工程師,985大學(xué)畢業(yè)的。他剛剛完成了一個(gè)不大不小的功能,為此他已經(jīng)連續(xù)加班了半個(gè)月。他寫下這行注釋后就提交了代碼,未來的工作就變得簡(jiǎn)單了,只要順著腦子里的思路往下寫就好,他甚至連未來可能要用到的參數(shù)都已經(jīng)預(yù)留好了。不過,這是他在騰訊地圖留下的最后一行代碼,隨即他遭到了騰訊地圖開除。原因當(dāng)然不是因?yàn)檫@行注釋,而是他在提交代碼的時(shí)候?qū)⒈镜毓ぷ鞣种Ц采w了主分支,并將它推送到了遠(yuǎn)端。這在騰訊地圖項(xiàng)目組引起了一場(chǎng)不大不小的轟動(dòng),他的上司為他出頭也受到波及,最終沒能留住他。他后來去了百度地圖,并將他在騰訊地圖所做的工作又依葫蘆畫瓢做了一遍。隨后他去了攜程,大概還是做地圖。后來他娶了一位鋼琴老師,在上海安了家,在我們那個(gè)小圈子里算是混的有頭有臉的了。
我所認(rèn)識(shí)的‘nimomeng’同學(xué)是一個(gè)動(dòng)不動(dòng)就愛刪庫的家伙,他在學(xué)習(xí)數(shù)據(jù)庫主外鍵時(shí)候,把自己的數(shù)據(jù)表用主外鍵關(guān)系捆稱了一團(tuán)亂麻,以至于任何的單表操作都會(huì)‘嘣’的一聲彈出主外鍵沖突警告。然后就刪庫,重新建表。我當(dāng)然看不慣他這樣搞?!氵@樣搞不費(fèi)勁嗎?’,我終于忍不住了。‘沒關(guān)系,這又搞不壞電腦,我還可以多練習(xí)一下sql命令’。隨后他向我展示了一下他所掌握的課堂上沒有講的諸多命令,尤其他向我演示‘xact_abort’命令的時(shí)候,我徹底嘆服。以后,隨他怎么亂搞主外鍵關(guān)系,我都不再說什么。
那些都是非常遙遠(yuǎn)的記憶了。言歸正傳,Git當(dāng)然并不復(fù)雜,也并非那么簡(jiǎn)單。問題在于你是否理解了git的基本原理,你是否對(duì)git的諸多命令背后的引發(fā)的副作用有清晰的認(rèn)知。天堂和地獄,都在一念之間。如果你之間有用過svn,將有助于你更好地理解git。
git的基本原理
Svn很像一個(gè)BBS聊天室的應(yīng)用,客戶端對(duì)信息的收發(fā)都經(jīng)過中心服務(wù)器的處理,由中心服務(wù)器集中處理所有消息,并群發(fā)給所有客戶端。svn的版本管理全部交由中心服務(wù)器處理,客戶端只做代碼提交和下載。git被稱為分布式版本控制,所謂分布式,即是所有g(shù)it客戶端都由自己獨(dú)立的倉庫。而所謂的遠(yuǎn)端,僅僅是相當(dāng)于一個(gè)FTP文件服務(wù)器,順便記錄一下你的上傳和下載操作。因此,git的核心是本地倉庫。下面就讓我們來了解一下本地倉庫的一些基本操作。
本地倉庫的基本操作。
和svn保存代碼文件不同,git記錄的是動(dòng)作快照。所謂快照,可以理解為是一條日志記錄,即記錄你的每一步git動(dòng)作。比如,你add一下,它會(huì)記錄。你rm一下,它也會(huì)記錄。當(dāng)你需要恢復(fù)以前的代碼狀態(tài)時(shí),就可以通過動(dòng)作回放來達(dá)到目的,就像數(shù)據(jù)庫可以通過日志恢復(fù)被刪除的Data文件一樣。是不是非常的簡(jiǎn)單呢?你還需要理解一下分支的概念,git的所有操作都基于分支的。本地版本庫就是一個(gè)分支集合,本地版本庫一旦創(chuàng)建,即會(huì)創(chuàng)建一個(gè)默認(rèn)分支master。這個(gè)分支除了不能刪除以外并沒有任何特別之處。一個(gè)分支相當(dāng)于一個(gè)日志文件,即在master分支下的任何操作都會(huì)記錄到master日志中,在wsj分支下的任何操作都會(huì)記錄到wsj日志中。因此,切換分支就相當(dāng)于切換不同的工作環(huán)境,在物理上,就相當(dāng)于切換到了不同的工作目錄。理解這一點(diǎn)非常關(guān)鍵,這是git最具特色的地方。這里只做理論上的概述,你如果不能理解它,請(qǐng)務(wù)必查閱其他資料,在腦子里形成一個(gè)非常具象的概念模型。關(guān)于分支,有以下細(xì)節(jié)需要注意:
1.本地版本庫一旦創(chuàng)建,就會(huì)創(chuàng)建一個(gè)本地Master分支,并將當(dāng)前工作分支切換到Master下。
2.在當(dāng)前工作分支創(chuàng)建另一個(gè)分支,并不是創(chuàng)建一個(gè)空分支,而是將當(dāng)前工作分支的所有快照記錄都復(fù)制給新的分支。
關(guān)于第二條,這里稍作一下解釋。比如,你創(chuàng)建一個(gè)空目錄,并用cmd命令進(jìn)入該目錄,在cmd中執(zhí)行g(shù)it init。這時(shí)候你就已經(jīng)出于master分支下,你在目錄中新建一個(gè)文件并通過add和commit將文件提交到master分支下。這時(shí),你在git branch xxx創(chuàng)建一個(gè)分支。你通過git checkout切換新分支下,會(huì)發(fā)現(xiàn)新分支的工作目錄并非是一個(gè)空目錄,而是有剛剛在master分支下添加的那個(gè)文件。關(guān)于這一點(diǎn),是很好理解的。如果不能理解,請(qǐng)?jiān)谌ゲ殚唲e的資料。那么,接下來,我們?cè)偃チ私庖幌耣ranch的基本結(jié)構(gòu)。
branch的基本結(jié)構(gòu)
branch在邏輯上相當(dāng)于一個(gè)日志文件,用于記錄本地的git動(dòng)作。在物理上,一個(gè)branch包含以下部分:
1.工作目錄 工作目錄是指工程目錄中除.git目錄的所有文件資源。
2.暫存區(qū) git add命令會(huì)將新增和修改內(nèi)容寫入暫存區(qū)。
3.版本庫 git commit命令將暫存區(qū)的內(nèi)容寫入版本庫。
由于在實(shí)際編碼中,經(jīng)常會(huì)新增和修改文件,因此,以下命令是用的最為頻繁的。
1.git add //將修改下入暫存去
2.git status //查看當(dāng)前工作目錄中的文件狀態(tài)
3.git commit // 將暫存區(qū)的內(nèi)容提交到版本庫中
將本地分支推送到遠(yuǎn)端
這一步非常的簡(jiǎn)單,我們可以通過git remote add 添加一個(gè)遠(yuǎn)端,并給遠(yuǎn)端設(shè)置一個(gè)別名。然后通過git push xxx 將當(dāng)前分支分支推送到遠(yuǎn)端。這里有一個(gè)細(xì)節(jié)非常需要注意,正是這個(gè)細(xì)節(jié)所隱藏的坑讓‘nomomeng’同學(xué)被騰訊地圖開除。git并不限制用戶只能推送本地master分支到遠(yuǎn)端,事實(shí)上,所有本地分支都能向遠(yuǎn)端推送。通常來說,我們都會(huì)將已經(jīng)完成的功能合并到本地master分支中,最后由master分支向遠(yuǎn)程推送,因此我們的本地master一般都和遠(yuǎn)程倉庫保持一致。但這并非git硬性規(guī)定的操作規(guī)則,而僅僅是一種大家都比較認(rèn)可的代碼提交策略。如果這一點(diǎn)不清楚,那么就極有可能犯錯(cuò)。千萬記住,git push 的時(shí)候一定明白自己push的是哪個(gè)分支,這個(gè)分支又是做什么用的。
關(guān)于git,在敲下每一行g(shù)it命令后,按回車之前請(qǐng)花兩秒鐘想想這個(gè)命令會(huì)引發(fā)什么樣的副作用,保持這樣的習(xí)慣,你就永遠(yuǎn)不會(huì)犯錯(cuò)誤。好了,就到這里吧,希望能對(duì)你有所幫助。
git init //初始化本地倉庫。
git clone //拷貝遠(yuǎn)程項(xiàng)目到本地
git diff //vim比較兩個(gè)分支之間的差異
git commit //將暫件移除git,不做物理傷處
git mv //移動(dòng)一個(gè)文件
git branch //列除當(dāng)前所有分支,如果后面加參數(shù)則是創(chuàng)建一個(gè)新分支
git checkout //切換分支存區(qū)修改提交到版本庫
git reset HEAD //撤銷暫存區(qū)修改,由版本庫內(nèi)容替換暫存區(qū)內(nèi)容
git rm //將文
git merge //將目標(biāo)分支合并到當(dāng)前分支