說說git(三)

git是一個實用的工具,在工作中,用得好,它能極大的提升你的工作效率;但用不好,它同樣會給你帶來麻煩,這一點我們在上一篇中有過詳細的描述。除了使用的規范性(git工作流)以外,在這一篇里,我會繼續延伸我對git的理解,希望能夠進一步打開你的腦洞,讓你和它之間的距離更近。

在互聯網公司,我認為git就是產品的中心,經驗證明,所有脫離git而獨立存在的協同軟件都是難以維護的,例如我以前就用trello或禪道在公司里推廣敏捷開發模式,用它們建立項目、拆分需求、分配任務,并專門給團隊進行培訓這些工具的使用方法。但最終都以失敗告終,具體原因是開發者總是忘了去這些協同軟件上修改狀態,每次都需要我來提醒,久而久之,就造成了協同軟件上的項目進度和實際進度不一致的情況,最后只好放棄使用。

深入追究這些工具不能持之以恒的原因,可能是因為這些辦公軟件并沒有幫助大家提升工作效率,反而卻增加了工作量,本來一次提交就意味著完成了任務,現在還要多出一步去打開一個頁面,并修改其中的狀態。

程序員都是很懶的。

所以理想的程序員會說,如果我提交一次,就完成了任務狀態的修改,那該多好,如果這樣,根本就不存在額外的推廣其他項目管理軟件的必要嘛。當想到這一點的時候,我突然明白了這不就是程序員必須具有的思維嗎,原來自己很長時間還沒有掌握這種思維。

最終,在近一年的工作中,我用這種方法逐漸的改善了以往的工作模式,即

能一步操作的事情,不要變成兩步來完成。

換句話說,既然git是程序員工作中的“必經之路”,那git一定就是連接其他一切的橋梁,我想,這應該也就是為什么有持續集成(continuous integration)這個概念的原因吧。具體一點,也就是利用git hooks的功能,在進行git操作后,執行一系列的事件,例如調用Trello的接口,修改任務的狀態為已完成或已解決,這樣做的好處也非常美好——它可以把一次提交和一個任務緊緊的聯系在一起,而不會出現提交了很多次之后,都不知道哪一次提交修改了哪些代碼的情況。

當然,如果你使用gitlab或github,上面說的把任務和編碼關聯在一起的功能,已經是這些軟件自帶的了,所以,我們現在使用gitlab,在gitlab上建立任務(issue)、開分支、編碼、提交、合并,完成后,任務會自動關閉掉,這個流程沒有任何一個多余的動作,也是理想的程序員希望達到的工作流程,詳細細節可以閱讀上一篇文章。

同樣的原理,我們可以在一次提交后做更多的事情,例如完成持續集成的幾個基本的步驟:

  1. 編譯
  2. 測試
  3. 打包
  4. 發布

實現方式同樣也是實現一個git hooks,當然這個世界上的很多輪子已經造好了,例如gitlab CI、Jenkins就是這樣的輪子,我們直接使用就行,如果理解了原理,肯定會更加得心應手。

下面是我編寫的一段go語言環境的gitlab CI腳本,通過它,你就可以一鍵完成項目的編譯、測試、打包這些過程了

# .gitlab-ci.yml
before_script:
  - PRJ_NAME=my_project
  - PRJ=$GOPATH/src/$PRJ_NAME
  - rm -f $PRJ
  - ln -s $CI_PROJECT_DIR $PRJ
  - PATH=$PATH:$GOROOT/bin:$GOPATH/bin
  
stages:
  - build
  - release
  - test
  
build:
  stage: build
  tags:
    - golang
  script:
    - cd $PRJ
    - make release
  except:
    - tags

release:
  stage: release
  artifacts:
    name: "${PRJ_NAME}_${CI_COMMIT_REF_NAME}"
    paths: 
    - build/
  script:
    - cd $PRJ
    - git submodule init
    - git submodule update
    - make release
  tags:
    - golang
  only:
    - tags   

test:
  stage: test
  tags:
    - golang
  script:
    - cd $PRJ
    - make test
  except:
    - tags

以上代碼中,before_script是初始化go的環境,stages告訴CI程序,要執行以下3個步驟:

  1. build——編譯
  2. release——打包
  3. test——測試

后續的以build、release、test開頭的代碼段,便是具體的這些步驟所需執行的代碼,可以看到這幾個步驟所執行的核心腳本是調用Makefile,執行make releasemake test,最大的區別是,release只有在打tag的時候才執行,而其他兩項是在不打tag的時候執行的。

也就是說,這個CI腳本完成了2個功能:

  1. 在日常提交時,gitlab會對代碼進行編譯和測試,確保該提交是通過了編譯和測試兩個環節的。
  2. 在發版前,項目經理會在production分支上打一個tag,這個動作會觸發release環節的執行,會把build目錄下的文件打包成一個帶有版本號的壓縮包,同時產生一個可下載的http鏈接,這樣做的好處也非常明顯,在服務器開發中,我覺得最大的好處是把開發和運維解耦了,這兩個部門間再也不會扯皮了。

通過這三篇文章,你應該對git由淺入深的有了一些認識,可以看到git對團隊協作、團隊成員間工作的透明性的威力很大,減少了噪音的同時,讓團隊更專注于核心的代碼層面上,這也是git的作者Linus所提倡的:

Talk is cheap, read the f**king code.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容