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