如何在團隊中實踐高品質的 Git 協作流程?
Git 版本控制實戰 的核心在於建立一套清晰、可追蹤且低耦合的開發秩序。高品質的 專案協作流程 包含:1. 原子化提交 (Atomic Commit):將每個 commit 限制在單一功能,降低還原風險;2. 約定式提交規範 (Conventional Commits):透過 feat: 或 fix: 等前綴,協助自動化工具生成語意化版號 (SemVer);3. 高品質 Pull Request (PR):提供明確的測試步驟與技術見解;4. 分支策略 (Git Flow):區分長期分支(Master, Develop)與短期分支(Feature, Hotfix)。掌握這些 軟體工程最佳實踐,能顯著提升程式碼審查效率,讓 Git 成為專案開發中最強大的時光機。
Git 版本控制:專案開發的時光機
Git 本身是一個分散式(一個遠端和很多本地端)的 版本控制系統 (VCS)。它會把每次提交的內容 (commit) 用快照透過校驗碼標示並儲存起來。校驗碼概念上可以當成車廂號碼,讓我們可以隨時查看特定版本中的檔案及狀態。掌握 Git 版本控制 是現代工程師的必備技能。
實際運作上,Git 比較像資料結構中的 Linked List,透過改變指標可以回到某個狀態,也可以自由地切割和移動節點。這份 專案協作與開發指南 將帶您深入了解其中的奧秘。
本日結果 -> 昨日結果 -> 前日結果
紀錄每個提交的項目主要會包含:
- Commit: 可以想成是指標
- Parents: 會指向前一個 commit
- Author: 用戶名稱
- Date: 日期
可以透過 git log 指令來查看過去紀錄:
1 | Commit ea8ccbae1371612578d7f4711719f56c1e425ed9 |
為什麼要使用 Git 版本控制:軟體工程的核心價值
人生就是不斷在後悔中持續成長
生命中的每個不同階段總有不少事情,會讓我們後悔當時怎麼沒有去做。在 軟體工程 中,Git 版本控制 提供了「後悔藥」的功能,讓我們能夠追蹤歷史、還原錯誤並優化架構。
比如你各位!!!當年學生時期喜歡上的那個男孩或女孩,為什麼當時就不懂得好好珍惜和努力?!說個我喜歡你很困難嗎?!
時光飛逝幾年過去,也許喜歡的那個誰已經有了小孩,而你,卻還在魯,這樣魯下去可以嗎?是不是很想回到過去?
雖然人生沒有辦法版本控制也沒辦法回到從前,但寫程式可以,到了專案不同的階段,也許也會想要再次回頭嘗試看看過去的解決方案。
- 使用前: 用資料夾版本控制
- 使用後: 除了版本訊息外更提供了切割和移動等進階功能
在個人開發上我們可以用來取代之前開資料夾的方式,還原也更為方便。
常見且小編使用過的版控服務有
- bitbucket: https://bitbucket.org/
- github: https://github.com/
- gitlab: https://about.gitlab.com/
- Azure DevOps: https://azure.microsoft.com/en-us/products/devops/
Git 初始化專案
首先要先安裝 Git,專案目錄輸入 git init 初始化版本控制,接著 git add . 加入所有目錄中相關檔案並執行 git commit 進行提交即可。
Git 協作實戰:原子化、約定式提交與合併請求
在 專案協作 或是跟團體共同開發程式時,為了減少衝突的發生並希望開發流程順暢,我們會遵循一系列的原則。這就是 Git 版本控制 在團隊開發中的實戰應用。
分支其實就是在快照上面新增一個指標,叫做分支的名稱,名稱就會指向那個校驗碼,方便切換過去。
1 | 本日結果1 - 昨日結果 - 前日結果 |
開源專案或是跟團體共同協作程式時,為了減少衝突的發生也希望大家都盡可能不受影響的開發,我們會希望大家都遵守一些流程和原則:
- 原子化提交 (Atomic Commit): 減少每個 commit 耦合,未來在還原或拆掉時也不需要確認太多事情。
- 約定式提交 (Conventional Commits): 方便之後 release 的統整。
- 合併請求 (Pull Request): 團隊成員的 commit 都會以 PR 當單位進入長期分支中。
- Git Flow 與 GitHub Flow: 按照團隊的規則讓 commit 們去到該去的地方。
原子化提交 (Atomic Commit):降低耦合與優化追蹤
原子化提交 的概念在許多地方都很適用,尤其是在 前端網頁設計 上。我們建議將每個 commit 限制在單一功能或修復中,這能有效降低程式碼耦合,讓未來的還原或重構更加輕鬆。
一個好的 commit 紀錄就是將這些東西按照步驟實作的過程,在前端專案,通常會是 component-based 的元件,所以元件或頁面的 commit 就會包含組成的過程。
- Layout
- theme or style
- render 邏輯
- 資料串接
以上面的例子來說,如果未來我們需要抽換主視覺,我們是不是就可以找到 theme style 的 commit 來進行複習修改即可?
約定式提交 (Conventional Commits):自動化版號管理的規範
約定式提交 規範是在程式碼提交時按照一組簡單的規則來建立明確的提交歷史。透過這種規範,自動化工具能協助我們產生語意化的版號,大幅提升 專案管理 的效率。
當然如果只有自己開發也沒有想要理解自己過去的歷史,那當然訊息可以隨便打個字元就好了。
當規範出現後,相關支援 SemVer 的自動化工具就能協助進行整理成語意化的版號,並且透過版號能夠看出背後的意涵。
訊息格式會像這樣 類型(範圍): 敘述,範圍通常用檔名,所以一個 commit 訊息可能會是:
BREAKING CHANGE(README.md): 影響功能
常用類型:
- fix(pencil): 什麼竟然有 typo
- feat(pencil): 加入橡皮擦變成擦擦筆
- perf(pencil): 2B 寬度變兩倍
其他可能有機會用到的:
- docs: 文件
- refactor: 重構
- revert: 復原
- style: 長相風格相關,不影響功能
- test: 測試功能
- chore: 打雜類的工作
語意化版本
語意化的版本號碼通常會有三個數字,舉例來說 v1.2.3 就代表 vMajor.Minor.Patch
- Major: 寫法或 API 可能不相容前一個版本
- Minor: 加了新的 feature 通常不影響前一個版本
- Patch: 修 bug 不影響前一個版本
回想我們升級相關套件的時候,是不是都會去看別人的 release note 或是 change log,當我們的 commit 都有規則,我們可以使用工具幫我們輕鬆做好這件事。
合併請求 (Pull Request):高品質的程式碼審查流程
當完成功能實作後,我們透過 合併請求 (Pull Request, PR) 與遠端分支同步。高品質的 PR 應包含預備知識、注意事項與測試步驟,這是確保 程式碼審查 (Code Review) 質量的關鍵。
當我們撰寫 PR 時,Review 程式碼的人可能是新人也可能很久沒看這部分,所以 PR 中盡可能去提供:
- 預備知識
- 需要特別注意的地方
- 有沒有未來可改善的
// TODO: - 測試步驟
有時候團隊成員其實不知道你怎麼會選擇這個解決方案,所以時間又更允許的話,可以盡可能提供當下的想法和見解給大家知道。
畢竟有的時候我們只有當下的最佳解,有的時候時間只夠我們 make it work,這時候就很適合留個 // TODO:,等到未來有空的時候大家知道可以 Make it right 甚至 Make it fast。
前同事 J: 當考慮解決方案的時候,想想每個解法的利弊,可以從更多面向看到不同的優缺點
狀態好的時候可以學著追求完美,至於狀態不好的時候,完整就謝天了,一個好的 PR
- 理論上只能有相關的 commit
- 每個 commit 最好不要更動太多檔案,會難以閱讀
前同事 W: 專案合作上,盡量保持多想想怎麼讓團隊每個人都舒服
當我們操作失當的時候,可能會發現 PR 中出現了很多不必要的 commit,其中一個原因可能是因為太久沒有跟遠端分支同步的關係,這時候:
同事可能 OS: 乾,你那什麼 PR,裡面一堆東西,我已經很忙了,這他媽一堆 commit 是要看三小??!
好同事可能就會提醒你說,沒關係不要緊張,因為好的 commit 紀錄是可以做出來的。
Commit 只需要東拼西湊整理好即可,當我們發現現在版本跟測試機或是正式機 (master) 差異過大時,有兩種方式
- 重新從 master 開新分支,一個個把需要的 commit 抓進來 (cherry-pick)
- 以 master 當 base 重新往下長我們的 commit,這就是 rebase 的用法
過程中也可以透過 rebase 互動模式拔掉 (drop) 或合併一些 (squash) 不想要的 commit,把現在的分支經過整理之後,重新發一個或是回去看看我們的 PR 這時候肯定就會發現真的整齊了不少,底下推薦三個常用指令
- 拆掉已經加上去的 Commit:
git reset --soft HEAD~1,數字表示移動到 HEAD 後面第幾個 - 把其他的 Commit 抓過來:
git cherry-pick ea8ccba - 整理 Commit:
git rebase -i ea8ccba
PR 合併策略
- Merge: 忠實紀錄完整呈現,但有時候線圖會穿插較不整齊且不易閱讀。
- Squash: 有一派的說法是當功能完成後,過去的 commit 都不重要,合併進去時就是一個 commit 紀錄我們完成了什麼功能即可。
- Rebase: 將起點移到最新,才進行合併,線圖會較整齊。
Git Flow 與 GitHub Flow:高效的分支管理模型
將程式碼加入 Git 版本控制 後,合理的 分支策略 (Branching Strategy) 是維持開發秩序的關鍵。Git Flow 與 GitHub Flow 是目前業界最主流的分支管理模型。
原則上主要分支是不會也不可以被協作者直接操作的,Git Flow 還建議專案 可以有其他分支如下:
- master: 長期存在的主要分支,可以看成是正式網站
- develop: 長期存在的開發分支,可以看成是測試站台
- hotfix: 短期分支,解完 bug 合併後可以看情況移除
- release: 短期分支,需要一點時間合併幾個 feature 才要一起 release
- feature: 短期分支,短期開發的小功能
當團隊開發時,情境如果是如果是新的 feature,然後大概一周內會合併進去 develop 我們就會:
- 先評估我們的東西屬於哪個類別 (feature),之後要進到哪個分支 (develop)
- 從 develop 開一個影分身的短期分支叫做 feature
- 團隊就會以 feature 為準,並在個人本機端上的開分支進行開發
- 個人分配的 feature 開發結束後,每個 Pull Request 都會對 feature 送
- 當經過團隊 review 之後就可以被 merge 進去 feature
- 所有的 feature 完成並測試後,再以 feature 分支對 develop 發 release 到測試站的 PR
- 測試無誤後就正式 release 到正式站
其實也有一說是當 CI/CD 及測試穩定時,如果產品版本不分散的話,團隊只需要一個 Master,任何改動及修改都對 Master 即可。
FAQ:Git 版本控制與協作常見問題
Q1:什麼是原子化提交 (Atomic Commit),為什麼它對前端開發很重要?
A:原子化提交 是指每個 commit 只包含一個邏輯上的修改(如:僅修改樣式、僅新增一個 API 介接)。這在 前端網頁設計 中尤為重要,因為前端程式碼常涉及視覺與邏輯的交織。如果一個 commit 同時修改了 10 個檔案且包含 3 個功能,當其中一個功能出錯需要 Revert 時,會非常難以拆分。高品質的原子化提交能讓 程式碼審查 更有焦點。
Q2:約定式提交 (Conventional Commits) 如何協助專案管理?
A:約定式提交規範 提供了一種標準化的語法(如 feat:, fix:)。這讓開發者一眼就能看出提交的本質。更重要的是,它能配合工具(如 Semantic Release)自動根據 commit 類型決定版本號的增量(Major/Minor/Patch),並自動生成高品質的 Change Log,大幅減少手動撰寫發布日誌的負擔。
Q3:在團隊開發中,Rebase 與 Merge 合併策略該如何選擇?
A:這取決於團隊對「線圖整潔度」的要求。Merge 會保留完整的歷史分岔,雖然真實但較凌亂。Rebase 能將您的開發歷史「接」在目標分支的最新處,產生一條線性的歷史,極具閱讀性。然而,Git Rebase 教學 的關鍵提醒是:千萬不要對已經推送到遠端的公共分支執行 Rebase,這會導致協作者的歷史錯亂。建議在個人分支整理完畢後再以 Rebase 合併。
喜歡這篇文章,請幫忙拍拍手喔 🤣