git管理複雜專案程式碼

mguy_1發表於2018-12-22

背景

我初學前端的時候接觸git,那時候只要會add/commit什麼的就好了,網上的教程大多都停留在從頭到尾一個個介紹git的命令,關於各種用法,特別是多個分支來回交叉衝突的實際處理,很少有這方面的介紹,經過很多次的實踐(踩雷?),想分享一點經驗,給剛進入前端的同學做過渡用,但畢竟一千個人有一千個使用git的方式,所以不保證對所有人都是有用的?

現在在公司開發維護一個比較大的專案,有公司自己實現的各種npm包、框架程式碼、各種業務公共程式碼和業務實現程式碼,總行數五六十萬行,頻繁的git提交經常導致程式碼翻車,經歷過多次車禍現場也算有點心得?。我司前端程式碼庫主要有dev/test/release環境分支(分別對應後端三個環境),幾個大的專案/特性分支和小百個業務分支,主要的規則就是自己開發的特性分支合併到dev(和後端聯調)=>合併到test(提交測試同學測試,改bug)=>合併release(測試同學模擬線上環境測試,準備釋出線上),說出來感覺非常清晰簡單,實際操作會有各種問題,有天災(臨時改需求,後臺改欄位),有人禍(提交程式碼不規範)。

外部的視覺化工具

如果不是特別熟悉git,還是先老實選一款git視覺化工具吧,推薦SourceTree(安裝後需要免費註冊,註冊要翻牆),之前用過GitHub Desktop,輕量的git工具,不能滿足複雜的需求,後來用了SourceTree,隨著版本的更新,越來越好用。 有關SourceTree的使用可以寫一篇文章,但是如果對git有稍深一點的理解,非常容易上手,節省了記命令的腦容量,節點圖也非常直觀。剛使用的同學建議多探索一下,很多操作如解決衝突、重置等比命令列要快,絕大部分命令都能用簡單的操作代替。如果git倉庫分支多而且關係複雜,純寫命令列的git老司機也容易翻車?

本地和遠端origin

提交程式碼之前請三思,如果是使用SourceTree,請不要在提交上點選同時推送到遠端(非常重要

git管理複雜專案程式碼
這樣提交以後,如果發現自己提交有問題還可以選擇更正上一次提交。我們公司的遠端倉庫除管理員無法回退,所以每次提交要非常謹慎,據說很久以前沒那麼多限制,大家在release/test上也隨意resetpush -f,回退的同時把這中間別人提交的程式碼也幹掉了,於是公司就禁止了除管理員以外對遠端倉庫的修改。理論上說在這三個環境分支release/test/dev上大家不應該直接提交,應該從其他分支改完merge過來,但是畢竟直接提交更方便,有個精度/樣式小bug之類的直接改掉,比切到相應業務分支改掉提交,切迴環境分支,merge過來更加的快,但是萬一提交出錯,就比較尷尬,所以還是不能懶。

提取單次提交cherry-pick

cherry-pick這個命令非常強大,也是我習慣SourceTree後唯二在命令列使用的git命令(還有revert merge),它是提取出某個分支的特定的那次提交應用到其他分支上,精準的操作,對其他程式碼不會造成任何影響。假如有個緊急bug,即將上線,我直接在release上改了,那麼事後一定要同步到自己的特性分支和test等其他環境分支,這時候又不想merge過去,就需要用到cherry-pick了,具體使用命令 git cherry-pick xxxxx,(xxxxx可以取簡略的那個commitId)

git管理複雜專案程式碼

回退revert及回退某次合併

分支多,合併也多,先說合並merge,merge xxx1 into xxx2這個命令中,xxx1是傳入分支,xxx2是當前分支,把xxx1分支上的程式碼合併到xxx2這個分支上,xxx1上新的程式碼就到了xxx2上了。比如我自己新開發的一個業務分支開發測試都搞得差不多,那我就準備合併到release,很好理解,但是合併完過一段時間被告知不對,不應該上去,產品還有別的想法?,那就revert吧,(由於前面的原因,reset是被禁止的)revert有優點,會隻影響那一次提交的的程式碼,但是缺點是會產生一個新的節點,revert merge又有不同,還拿上面的例子,假如提前合併上了不該上的程式碼,那隻能revert,具體程式碼git revert xxxxx -m 1 xxxxx還是commitId,1表示當前分支為準,2表示傳入分支為準,一般都是1,然後自己的特性分支又改了很多,等到了要上release的時候是沒法在直接merge的,因為revert是一個比較新的節點,這樣就要再次revert那個revert提交的commit(和第一次commit不一樣,是revert的commit),完了再進行merge自己特性分支最新的程式碼就可以了(來回merge加revert超亂的,下次誰出問題直接打死他?)

分支汙染

分支汙染這個問題主要是針對多個開發任務並行的情況,比如這個優惠券功能打算下週上,那個價格比對功能下下週上,那麼這兩個分支千萬不能互相合並,或者間接合並,道理很簡單,但是任務一多很容易亂,還有,多個特性任務分支可以隨時把release合併進來(最好經常合併以保持同步),因為這是最終版本,但是不能合併除release之外的其他分支,特別是test/dev分支,test/dev分支上存在了許多各種橫死的/半死的專案,這些千萬不能出到其他分支,要不然其他分支上到release就把這些垃圾內容帶過去上線。總之,各公司情況不同,但是大致結構差不多,把握好單向的程式碼流就好。

複雜場景

實際情況可能很複雜,因為我們公司用json來儲存使用者級的各種配置,tsx對某些大型元件裡面欄位型別做校驗,這些都是自動生成的,有時候只改了一點配置,就生成了一大堆更改,這樣的反覆多人在不同分支修改以後,一合併衝突的連它媽都不認識了,這個仍是當前專案的痛點,有可能每次合併就要花去單人半天一天的工作量,這樣的只能手動修改合併,藉助編輯器內部工具,如果後期有時間可能會把node層json配置改為mongoDB,但是本地json配置還沒有好辦法,歡迎留言區提出方案。

編輯器內部git工具(vscode的gitlens和webstorm)

vscode裡面的必裝外掛gitlens最近進行了更新,合併等功能已經快趕上webstorm了,合併的三欄式佈局適合修改一些複雜衝突,左右是當前以及傳入的程式碼,中間是自己的修改,非常的科學,還有很多功能如檢視當前這個檔案所有的歷史更改,與某個分支的某個檔案的快速比對等等功能,解決了複雜專案的很多痛點。

提交鉤子及繞過

公司對git有很多規範,禁止了push -f,對commit提交的備註資訊做了限制,這個是在自己專案的.git/hooks/裡面有限制,可以自己修改,我們統一是必須攜帶JIRA任務號,便於JIRA統計或者提交的是merge資訊,但如果想跳過的話(規則就是用來打破的,?),可以在SourceTree提交裡設定繞過鉤子提交

tag的問題

實際在多人協作專案裡使用git,基本沒有打過tag,tag的問題就在於如果和分支名字一樣,切換/合併分支容易到tag,而且打了錯誤的不合適的tag,必須遠端和所有本地一起刪除tag,要不然只要有一個人本地有tag,一push又到了遠端,難以去除,一般都是在運維用jenkins部署時打個上線日期tag,便於回退(但是如果jenkins部署打的tag不規範、重名,也會引發前端程式碼庫提交各類問題)。

總結

git這東西說簡單也簡單,說難有的問題直撓頭皮,但是我覺得,最重要的是要養成一個好的提交習慣,提交本地前先三思,提交到遠端前再想一遍,避免翻車,對團隊程式碼造成災難型的後果,影響他人工作。 純手敲出這麼多字,如果感覺有些幫助,那我就很滿足了,如果有問題儘管提,共同進步!

相關文章