您必須知道的 Git 分支開發規範,附 Git 常用命令大全!

我們都知道,阿里有 Java 規範,Redis 規範,而 Git 規範幾乎從未被聊起,所以,今天我就說一說 Git 的日常分支開發規範。

先說分支命名規範。

master 分支:master 為主分支,也是用於部署生產環境的分支,確保 master 分支穩定性;master 分支一般由 develop 以及 hotfix 分支合併,任何時間都不能直接修改程式碼。

develop 分支:develop 為開發分支,始終保持最新完成以及 bug 修復後的程式碼;一般開發的新功能時,feature 分支都是基於 develop 分支下創建的。

feature 分支:開發新功能時,以 develop 為基礎創建 feature 分支;分支命名以 feature/ 開頭的為特性分支,命名規則 feature/user_module、 feature/cart_module。

release 分支:release 為預上線分支,發布提測階段,會 release 分支程式碼為基準提測。

當有一組 feature 開發完成,首先會合併到 develop 分支,進入提測時,會創建 release 分支。如果測試過程中若存在 bug 需要修復,則直接由開發者在 release 分支修復並提交。當測試完成之後,合併 release 分支到 master 和 develop 分支,此時 master 為最新程式碼,用作上線。

hotfix 分支:分支命名以 hotfix/ 開頭的為修復分支,它的命名規則與 feature 分支類似;線上出現緊急問題時,需要及時修復,以 master 分支為基準線,創建 hotfix 分支,修復完成後,需要合併到 master 分支和 develop 分支。

使用 Git 添加新功能的示例如下:

(dev)$: git checkout -b feature/xxx  # 從dev建立特性分支  (feature/xxx)$: blabla  # 開發  (feature/xxx)$: git add xxx  (feature/xxx)$: git commit -m 'commit comment'  (dev)$: git merge feature/xxx --no-ff  # 把特性分支合併到dev

修復緊急 bug 示例:

(master)$: git checkout -b hotfix/xxx  # 從master建立hotfix分支  (hotfix/xxx)$: blabla  # 開發  (hotfix/xxx)$: git add xxx  (hotfix/xxx)$: git commit -m 'commit comment'  (master)$: git merge hotfix/xxx --no-ff # 把hotfix分支合併到master,並上線到生產環境  (dev)$: git merge hotfix/xxx --no-ff  # 把hotfix分支合併到dev,同步程式碼

測試環境合併示例:

(release)$: git merge dev --no-ff  # 把dev分支合併到release,然後在測試環境拉取並測試

線上生產環境操作示例:

(master)$: git merge release --no-ff  # 把release測試好的程式碼合併到master,運維人員操作  (master)$: git tag -a v0.1 -m '部署包版本名'  #給版本命名,打Tag

提交日誌規範:在一個團隊協作的項目中,開發人員需要經常提交一些程式碼去修復 bug 或者實現新的 feature。而項目中的文件和實現什麼功能、解決什麼問題都會漸漸淡忘,最後需要浪費時間去閱讀程式碼。但是好的日誌規範 commit messages 編寫有幫助到我們,它也反映了一個開發人員是否是良好的協作者。

編寫良好的 Commit messages 可以達到3個重要的目的:

  • 加快 review 的流程
  • 幫助我們編寫良好的版本發布日誌
  • 讓之後的維護者了解程式碼里出現特定變化和 feature 被添加的原因

目前,社區有多種 Commit message 的寫法規範。來自 Github 上的 Angular 規範是目前使用最廣的寫法,比較合理和系統化。如下圖:

Commit messages 的基本語法規範。

當前業界應用的比較廣泛的是 Angular Git Commit Guidelines,

具體格式為:

<type>: <subject>  <BLANK LINE>  <body>  <BLANK LINE>  <footer>
  • type: 本次 commit 的類型,諸如 bugfix docs style 等
  • scope: 本次 commit 波及的範圍
  • subject: 簡明扼要的闡述下本次 commit 的主旨,在原文中特意強調了幾點 1. 使用祈使句,是不是很熟悉又陌生的一個詞,來傳送門在此 祈使句 2. 首字母不要大寫 3. 結尾無需添加標點
  • body: 同樣使用祈使句,在主體內容中我們需要把本次 commit 詳細的描述一下,比如此次變更的動機,如需換行,則使用 |
  • footer: 描述下與之關聯的 issue 或 break change。

Type的類別說明:

  • feat: 添加新特性
  • fix: 修復 bug
  • docs: 僅僅修改了文檔
  • style: 僅僅修改了空格、格式縮進、都好等等,不改變程式碼邏輯
  • refactor: 程式碼重構,沒有加新功能或者修復 bug
  • perf: 增加程式碼進行性能測試
  • test: 增加測試用例
  • chore: 改變構建流程、或者增加依賴庫、工具

Commit messages 格式要求。

# 標題行:50個字元以內,描述主要變更內容  #  # 主體內容:更詳細的說明文本,建議72個字元以內。需要描述的資訊包括:  #  # * 為什麼這個變更是必須的? 它可能是用來修復一個bug,增加一個feature,  # 提升性能、可靠性、穩定性等等  # * 他如何解決這個問題? 具體描述解決問題的步驟  # * 是否存在副作用、風險?  #  # 如果需要的化可以添加一個鏈接到issue地址或者其它文檔

最後列舉一些我們團隊人手列印一份的 Git 常用命令清單。

新建程式碼庫常用命令。

# 在當前目錄新建一個Git程式碼庫  $ git init  # 新建一個目錄,將其初始化為Git程式碼庫  $ git init [project-name]  # 下載一個項目和它的整個程式碼歷史  $ git clone [url]

Git 的設置文件為 .gitconfig,它可以在用戶主目錄下(全局配置),也可以在項目目錄下(項目配置)。

# 顯示當前的Git配置  $ git config --list  # 編輯Git配置文件  $ git config -e [--global]  # 設置提交程式碼時的用戶資訊  $ git config [--global] user.name "[name]"  $ git config [--global] user.email "[email address]"

增加/刪除文件命令。

# 添加指定文件到暫存區  $ git add [file1] [file2] ...  # 添加指定目錄到暫存區,包括子目錄  $ git add [dir]  # 添加當前目錄的所有文件到暫存區  $ git add .  # 添加每個變化前,都會要求確認  # 對於同一個文件的多處變化,可以實現分次提交  $ git add -p  # 刪除工作區文件,並且將這次刪除放入暫存區  $ git rm [file1] [file2] ...  # 停止追蹤指定文件,但該文件會保留在工作區  $ git rm --cached [file]  # 改名文件,並且將這個改名放入暫存區  $ git mv [file-original] [file-renamed]

程式碼提交命令。

# 提交暫存區到倉庫區  $ git commit -m [message]  # 提交暫存區的指定文件到倉庫區  $ git commit [file1] [file2] ... -m [message]  # 提交工作區自上次commit之後的變化,直接到倉庫區  $ git commit -a  # 提交時顯示所有diff資訊  $ git commit -v  # 使用一次新的commit,替代上一次提交  # 如果程式碼沒有任何新變化,則用來改寫上一次commit的提交資訊  $ git commit --amend -m [message]  # 重做上一次commit,並包括指定文件的新變化  $ git commit --amend [file1] [file2] ...

分支管理命令。

# 列出所有本地分支  $ git branch  # 列出所有遠程分支  $ git branch -r  # 列出所有本地分支和遠程分支  $ git branch -a  # 新建一個分支,但依然停留在當前分支  $ git branch [branch-name]  # 新建一個分支,並切換到該分支  $ git checkout -b [branch]  # 新建一個分支,指向指定commit  $ git branch [branch] [commit]  # 新建一個分支,與指定的遠程分支建立追蹤關係  $ git branch --track [branch] [remote-branch]  # 切換到指定分支,並更新工作區  $ git checkout [branch-name]  # 切換到上一個分支  $ git checkout -  # 建立追蹤關係,在現有分支與指定的遠程分支之間  $ git branch --set-upstream [branch] [remote-branch]  # 合併指定分支到當前分支  $ git merge [branch]  # 選擇一個commit,合併進當前分支  $ git cherry-pick [commit]  # 刪除分支  $ git branch -d [branch-name]  # 刪除遠程分支  $ git push origin --delete [branch-name]  $ git branch -dr [remote/branch]

標籤操作命令。

# 列出所有tag  $ git tag  # 新建一個tag在當前commit  $ git tag [tag]  # 新建一個tag在指定commit  $ git tag [tag] [commit]  # 刪除本地tag  $ git tag -d [tag]  # 刪除遠程tag  $ git push origin :refs/tags/[tagName]  # 查看tag資訊  $ git show [tag]  # 提交指定tag  $ git push [remote] [tag]  # 提交所有tag  $ git push [remote] --tags  # 新建一個分支,指向某個tag  $ git checkout -b [branch] [tag]

查看一些資訊的常用命令。

# 顯示有變更的文件  $ git status  # 顯示當前分支的版本歷史  $ git log  # 顯示commit歷史,以及每次commit發生變更的文件  $ git log --stat  # 搜索提交歷史,根據關鍵詞  $ git log -S [keyword]  # 顯示某個commit之後的所有變動,每個commit佔據一行  $ git log [tag] HEAD --pretty=format:%s  # 顯示某個commit之後的所有變動,其"提交說明"必須符合搜索條件  $ git log [tag] HEAD --grep feature  # 顯示某個文件的版本歷史,包括文件改名  $ git log --follow [file]  $ git whatchanged [file]  # 顯示指定文件相關的每一次diff  $ git log -p [file]  # 顯示過去5次提交  $ git log -5 --pretty --oneline  # 顯示所有提交過的用戶,按提交次數排序  $ git shortlog -sn  # 顯示指定文件是什麼人在什麼時間修改過  $ git blame [file]  # 顯示暫存區和工作區的差異  $ git diff  # 顯示暫存區和上一個commit的差異  $ git diff --cached [file]  # 顯示工作區與當前分支最新commit之間的差異  $ git diff HEAD  # 顯示兩次提交之間的差異  $ git diff [first-branch]...[second-branch]  # 顯示今天你寫了多少行程式碼  $ git diff --shortstat "@{0 day ago}"  # 顯示某次提交的元數據和內容變化  $ git show [commit]  # 顯示某次提交發生變化的文件  $ git show --name-only [commit]  # 顯示某次提交時,某個文件的內容  $ git show [commit]:[filename]  # 顯示當前分支的最近幾次提交  $ git reflog

遠程同步命令。

# 下載遠程倉庫的所有變動  $ git fetch [remote]  # 顯示所有遠程倉庫  $ git remote -v  # 顯示某個遠程倉庫的資訊  $ git remote show [remote]  # 增加一個新的遠程倉庫,並命名  $ git remote add [shortname] [url]  # 取回遠程倉庫的變化,並與本地分支合併  $ git pull [remote] [branch]  # 上傳本地指定分支到遠程倉庫  $ git push [remote] [branch]  # 強行推送當前分支到遠程倉庫,即使有衝突  $ git push [remote] --force  # 推送所有分支到遠程倉庫  $ git push [remote] --all

撤銷相關操作命令。

# 恢復暫存區的指定文件到工作區  $ git checkout [file]  # 恢復某個commit的指定文件到暫存區和工作區  $ git checkout [commit] [file]  # 恢復暫存區的所有文件到工作區  $ git checkout .  # 重置暫存區的指定文件,與上一次commit保持一致,但工作區不變  $ git reset [file]  # 重置暫存區與工作區,與上一次commit保持一致  $ git reset --hard  # 重置當前分支的指針為指定commit,同時重置暫存區,但工作區不變  $ git reset [commit]  # 重置當前分支的HEAD為指定commit,同時重置暫存區和工作區,與指定commit一致  $ git reset --hard [commit]  # 重置當前HEAD為指定commit,但保持暫存區和工作區不變  $ git reset --keep [commit]  # 新建一個commit,用來撤銷指定commit  # 後者的所有變化都將被前者抵消,並且應用到當前分支  $ git revert [commit]  # 暫時將未提交的變化移除,稍後再移入  $ git stash  $ git stash pop

生成發布包命令。

# 生成一個可供發布的壓縮包  $ git archive

以上,你知道的越多,不知道的就越多,業餘的像一棵小草一樣。