Commit Message「fix」「update」「WIP」
fix
update
WIP
asdf
ok
changes
這些 message 告訴你「有東西被改了」,但沒有告訴你為什麼改、改了什麼、影響範圍是什麼。六個月後 git blame 看到這些,完全無從判斷這個改動的脈絡。
好的 commit message 格式(Conventional Commits):
fix(auth): handle expired JWT gracefully instead of 500 error
When a JWT expires, the middleware was throwing an unhandled exception.
Changed to return 401 with a clear error message so clients can refresh.
Closes #234
第一行說 what + where。Body 說 why 和背景(選填但有價值)。
長期存活的 Feature Branch
Feature branch 存活超過兩週,merge 時需要解決大量 conflict,而且整合問題只有在最後才發現——代價最高的時機。
更糟的是多個長期 branch 並行:branch-A 和 branch-B 都從 main 分出去,各自修改了同一個地方,最後 merge 的那個人要解決所有衝突。
修法:縮短 branch 壽命(1-3 天),用 feature flag 隱藏未完成功能,頻繁 rebase / merge from main。
Force Push 到共用 Branch
git push --force origin main # 把同事的 commit 覆蓋掉Force push 重寫了遠端 history,其他正在使用這個 branch 的人的本機 history 和遠端不一致,他們下次 pull 時會陷入混亂。
唯一合理的 force push 場景:你自己的個人 feature branch,且你確認沒有人在使用它。
替代方案:git push --force-with-lease——只在遠端 branch 和你預期的 commit 一致時才允許 force push,防止覆蓋別人的工作。
不加 .gitignore 就 Commit
.env、node_modules/、*.pyc、.DS_Store、IDE 設定(.idea/)進了 repo:
.env可能含有 API key、DB 密碼——已知最常見的 secret 洩漏路徑之一node_modules/讓 repo 膨脹數 GB,PR diff 變得無法閱讀- IDE 設定讓每個工程師的 git status 都是 dirty
從一開始就設定 .gitignore。GitHub 在建立 repo 時可以自動生成語言對應的 .gitignore。gitignore.io 可以生成多語言的模板。
Merge 不解 Conflict 直接丟遠端
git merge main
# 有 conflict,直接
git checkout --theirs . # 取遠端所有改動,本機的全丟
git add .
git commit這不是「解決衝突」,是「選一邊放棄」。你的 code 或同事的 code 就這樣消失了,而且 git history 看不出任何問題。
正確做法:打開有衝突的檔案,逐一理解「我的改動是什麼」和「他們的改動是什麼」,然後做出整合兩者的版本——或者討論後決定取哪一邊。
在 PR 裡塞太多東西
一個 PR 包含:新功能 + 重構 + bug fix + style 調整。reviewer 需要理解所有的背景才能做有意義的 review,而且 revert 時只能整體 revert 無法選擇性。
原則:每個 PR 只做一件事。重構和功能分開 PR,bug fix 和 feature 分開 PR。PR 越小,review 越快,風險越低。
不善用 Git Blame 和 Log
在 code 裡看到一個奇怪的 if 判斷,不知道為什麼存在,直接刪掉。結果這個判斷是為了 workaround 某個外部服務的邊界情況,刪掉後 bug 復現。
在改動舊 code 之前先 git blame:看這行是誰、什麼時候加的、關聯的 commit message 說了什麼。大多數「看起來多餘」的 code 都有它存在的原因,只是藏在 history 裡。
# 看某個檔案每行的最後一次修改者和 commit
git blame src/payment/processor.py
# 搜尋 commit message 包含特定關鍵字
git log --all --grep="workaround"
# 找某個字串什麼時候被加進來
git log -S "LEGACY_PAYMENT_GATEWAY" --source --all