入职第一天就把main分支搞崩了——我的Git血泪史和团队规范诞生记
å ¥è第ä¸å¤©å°±æmain忝æå´©äºââæçGitè¡æ³ªå²åå¢éè§èè¯çè®°
badhope 2026-08-08 0 é 读17åéå ¥è第ä¸å¤©å°±æmain忝æå´©äºââæçGitè¡æ³ªå²åå¢éè§èè¯çè®°
å¨ä¸æ©ä¸ä¹ç¹ï¼ææçå ¥èææèµ°è¿æ°å ¬å¸ï¼å·¥ä½è¿æ²¡åçï¼å¯¼å¸å°çå°±ç©è¿æ¥ä¸ä¸ªGitLabå°åï¼"å æä»£ç æä¸æ¥è·ä¸ä¸ï¼ä¸åè¦æ¹ä¸ªbugã"
æå¿æ³è¿æä»ä¹é¾çï¼git clone䏿æ¢ï¼ç¶ågit push --forceæææ¬å°æ¹çä¸è¥¿ç´æ¥æ¼ä¸å»ãååéåï¼å
¬å¸ç¾¤éCTOåäºä¸ä¸ªé®å·ã
å°±ä¸ä¸ªé®å·ãä½é£ä¸ªé®å·ï¼æ¯æè§è¿çä»»ä½ä»£ç è¯å®¡æè§é½è®©äººçªæ¯ã
第ä¸å¤©ï¼ä»force pushå°"æéäº"
äºæ
æ¯è¿æ ·çãæcloneå®ä»£ç åï¼å¨main忝ä¸ç´æ¥æ¹äºç¹ä¸è¥¿ï¼git add . && git commit -m "fix bug"ï¼ç¶åæ¨ä¸ä¸å»ââæç¤ºè¿ç¨ææ´æ°ãæå½æ¶èåéåªæä¸å¥è¯ï¼"pushä¸ä¸å»å°±force pushåï¼Stack Overflowä¸é½æ¯è¿ä¹åçã"
# æå½æ¶æ§è¡ç"æ¶éæä»¤"
git push --force origin main
# ç¶åå°çå¨ç¾¤éè¯´ï¼æåæäº¤ç代ç å¢ï¼ï¼ï¼
é£ä¸å»ææç¥éï¼--force䏿¯"强å¶è¦çæèªå·±ç代ç "ï¼æ¯"强å¶è¦çææäººç代ç "ãå°çä¸ååæäº¤çä¸ä¸ªæ¥å£ä¼åï¼ç´æ¥è¢«æçæä½å²æ²¡äºã
è¿å¥½Gitæreflogï¼CTOæ·¡å®å°æäºä¸è¡å½ä»¤æå°ççæäº¤æ¾åæ¥äºï¼
# æ¾å被è¦ççæäº¤
git reflog
git reset --hard <å°ççcommit hash>
git push --force origin main
# CTOåªè¯´äºä¸å¥ï¼ä»¥åå«å¨mainä¸ç´æ¥æä½
æå½åºå°±æ³æ¾ä¸ªå°ç¼é»è¿å»ãå ¥è第ä¸å¤©å°±æmain忝æå´©ï¼è¿è®°å½ææ¯æ²¡äººè½ç ´äºã忥å°çåè¯æï¼ä»å½æ¶å¨å·¥ä½ä¸æ£åå¤å»åæ°´ï¼çå°GitLabæ¨ééç¥éæçåååºç°å¨main忝ä¸ï¼æ°´é½æ²¡åç´æ¥è·åæ¥äºã
"ä½ ç¥émain忝æå³çä»ä¹åï¼"å°çå卿æè¾¹ï¼è¯æ°åæ¯å¨åä¸ä¸ªåé¯ç¥¸çå°å©ï¼"mainæ¯ç产ç¯å¢ç代ç ã线ä¸è·çå°±æ¯è¿ä¸ªåæ¯ãä½ force pushè¦çäºä¹åï¼å¦ææäººå¨è¿ä¸ªé´ééé¨ç½²äºï¼çº¿ä¸ç´æ¥å°±æ¯ä½ çåæå代ç ã"
æå¬äºåèååã好å¨é¨ç½²ç³»ç»æå®æ¶ä»»å¡ï¼é´éæ¯ä¸ååéï¼èCTOå¨ååéå å°±æ¢å¤äºä»£ç ã妿åæäºåå åéï¼åæä¸å ªè®¾æ³ã
è¿ä»¶äºè®©æç¬¬ä¸æ¬¡æè¯å°ï¼Gitä¸åªæ¯ä¸ä¸ª"ä¿å代ç çå·¥å ·"ãå¨ä¸ä¸ªå¢ééï¼Gitæ¯ææäººå ±äº«ç代ç åºç¡è®¾æ½ï¼ä½ çæ¯ä¸æ¬¡pushé½å¯è½å½±åå°å«äººãä¸ä¸ªäººç¨Gitåä¸ç¾¤äººç¨Gitï¼å®å ¨æ¯ä¸¤ä¸ªä¸çã
ä¸åï¼å°çç»æè®²äºç¬¬ä¸æ¡Gitè§ç©ï¼æ°¸è¿ä¸è¦å¨main忝ä¸ç´æ¥å¼åãè¦å æåæ¯ï¼æ¹å®ååå¹¶ãä»ç»äºä¸å¼ å¾ï¼main忝忝䏿¡ä¸»å¹²éï¼ä½ ä¸å¨ä¸»å¹²é䏿½å·¥ï¼èæ¯å¼ä¸æ¡ä¾¿éï¼feature忝ï¼ï¼å¹²å®æ´»å¿åæä¾¿éå¹¶å主干éãè¿æ ·å³ä½¿ä¾¿éä¸åºäºé®é¢ï¼ä¸»å¹²éä¸åå½±åã
# æ£ç¡®çå§¿å¿
git checkout -b feature/fix-login-bug
# æ¹ä»£ç ...
git add .
git commit -m "fix: ä¿®å¤ç»å½é¡µé¢ç©ºæéå¼å¸¸"
git push origin feature/fix-login-bug
# ç¶åå¨GitLabä¸åèµ·Merge Request
æå¦å°äºãä½ç¬¬äºå¤©ï¼æåæåºäºæ°è±æ ·ã
第äºå¤©ï¼åæ¯å"fix-bug-final-v2-real"
第äºå¤©æå¦ä¹äºï¼ç¥éè¦æåæ¯ãä½åæ¯å½åè¿ä¸ªäºï¼æ²¡äººæè¿æãæç忝忼å岿¯è¿æ ·çï¼
# æç忝å½å"è¿åå²"
git checkout -b fix-bug # 太笼ç»
git checkout -b fix-bug-final # ä»ä¹å«finalï¼
git checkout -b fix-bug-final-v2 # è¿æv2ï¼
git checkout -b fix-bug-final-v2-real # ç¶årealæ¯ä»ä¹ææï¼ï¼ï¼
å°ççå°æç忝åï¼æ²é»äºäºç§ï¼ç¶å说ï¼"ä½ ç¥éæä»¬GitLabä¸ç°å¨æå¤å°ä¸ªå«fix-bugå¼å¤´ç忝åï¼åä¸ä¸ªãå
¶ä¸åäºä¸ªæ¯ä½ çã"
忝å½åè§èï¼
ç±»å/ç®çæè¿°ï¼ç±»åå æ¬ featureï¼æ°åè½ï¼ãfixï¼ä¿®å¤ï¼ãhotfixï¼ç´§æ¥ä¿®å¤ï¼ãrefactorï¼éæï¼ãdocsï¼ææ¡£ï¼ãæè¿°ç¨è±æå°åï¼åè¯é´ç¨è¿å符ãä¾å¦ï¼feature/user-avatar-uploadãfix/login-null-pointerã
æèèå®å®æåæ¯å äºéæ°å»ºï¼
# å ææ¬å°åè¿ç¨çç忝
git branch -D fix-bug-final-v2-real
git push origin --delete fix-bug-final-v2-real
# éæ°å½å
git checkout -b fix/login-null-pointer
ç¶åæéå°äºæ´å¤§ç婿¢¦ââmergeå²çªã
é£å¤©ä¸åï¼ææ¹å®ä»£ç åå¤åå¹¶å°mainï¼Gitæç¤ºæå²çªãææå¼å²çªæä»¶ä¸çï¼æ»¡å±ç<<<<<<< HEADã=======ã>>>>>>>ï¼æ´ä¸ªäººç´æ¥æµäºã
æå½æ¶çè§£å³æ¹æ¡æ¯ï¼æå¨ä¸ä¸ªå符ä¸ä¸ªåç¬¦å°æ¹ãæå¼VS Codeçåå¹¶ç¼è¾å¨ï¼å·¦è¾¹æ¯æçæ¹å¨ï¼å³è¾¹æ¯ä»çæ¹å¨ï¼ä¸é´æ¯åå§ä»£ç ãæççæ»¡å±ç红绿æ è®°ï¼æè§èªå·±ä¸æ¯å¨è§£å³å²çªï¼èæ¯å¨åä¸éé 读çè§£é¢ââèä¸è¿æ²¡ææ åçæ¡ã
æ¹äºä¸ä¸ªå°æ¶ï¼æ¹å®ä»¥åè¿ä¸ç¡®å®å¯¹ä¸å¯¹ãæææä»¶ä¿åäºï¼è¿è¡äºä¸ä¸é¡¹ç®ï¼å± ç¶è½è·èµ·æ¥ãææ¾äºå£æ°ï¼è§å¾è¿äºå°±ç®è¿å»äºãç»æå°çè¿æ¥code reviewï¼ç宿çå²çªè§£å³æ¹æ¡ï¼å·®ç¹åæ³ææå¼é¤äºã
"ä½ è¿ä¸ªå²çªè§£å³å¾æé®é¢ï¼ä½ æå¯¹æ¹ç代ç å ¨å äºï¼åªçäºä½ èªå·±çã"å°ç说è¿è¯çæ¶å表æ å¾å¤æï¼åæ¯çå°äºä»ä¹ä¸å¯æè®®çä¸è¥¿ã
æä½å¤´ä¸çï¼è¿çæ¯ãå²çªæ è®°=======ä¸é¢ç代ç ï¼æçï¼å
¨ä¿çäºï¼ä¸é¢ç代ç ï¼å°ççï¼å
¨å äºãææ ¹æ¬æ²¡ä»ç»ç两边æ¹äºä»ä¹ï¼åªæ¯æºæ¢°å°éæ©äº"ä¿çèªå·±ç"ã妿å°ç没æreviewå°±åå¹¶äºï¼ä»ä¸ååçæ¥å£ä¼åå°±å被æå¹²æäºââå·®ç¹éæ¼æ©ä¸çäºæ
ã
"è§£å³å²çªä¸æ¯éè¾¹ç«ï¼"å°çæ·±å¸ä¸å£æ°ï¼"ä½ è¦çè§£ä¸¤è¾¹é½æ¹äºä»ä¹ï¼ç¶ååå¹¶æä¸ä¸ªæ£ç¡®ççæ¬ãææ¶å两边é½å¯¹ï¼ææ¶å两边é½éäºï¼ä½ å¾èªå·±å¤æã"
é£å¤©æä¸æåå®¶åï¼æGit宿¹ææ¡£éå
³äºmerge conflictçé¨åä»å¤´çäºä¸éãå
¶å®Gitå·²ç»æå²çªæ è®°å¾å¾æ¸
æ¥äºï¼<<<<<<< HEADå°=======ä¹é´æ¯ä½ å½åç代ç ï¼=======å°>>>>>>>ä¹é´æ¯å¯¹æ¹ç代ç ãä½ éè¦åçæ¯ç解两边çæå¾ï¼æå¨ç¼è¾ææ£ç¡®çç»æã
è¿å¦å°äºä¸ä¸ªæå·§ï¼å¦æå²çªå¤ªå¤æï¼å¯ä»¥ç¨ä¸æ¹åå¹¶å·¥å ·ãGitä¼ä¿çåå§çæ¬ï¼å ±åç¥å ï¼ï¼ä½ 对æ¯åå§çæ¬å°±è½çåºæ¯ä¸ªäººå°åºæ¹äºä»ä¹ï¼ä»èååºæ£ç¡®çåå¹¶å³çãVS CodeãIntelliJé½å ç½®äºå¯è§å䏿¹åå¹¶å·¥å ·ï¼æ¯çº¯ææ¬ç¼è¾å¼ºå¤ªå¤äºã
第ä¸å¤©ï¼åç°rebaseçåå¨
第ä¸å¤©ï¼æå³å®å¥½å¥½ç ç©¶ä¸ä¸Gitãä¸çä¸ç¥éï¼ä¸çåç°æä¹åç¨çåªæ¯Gitçå°å±±ä¸è§ã
# 以åæåå¹¶ä»£ç æ¯è¿æ ·ç
git checkout main
git merge feature/xxx
# 妿æå²çªï¼merge commitä¼åå¾å¾ä¹±
# 忥æå¦ä¼äºrebase
git checkout feature/xxx
git rebase main
# ææç忝"嫿¥"å°mainææ°æäº¤ä¹ä¸
# å²çªè§£å³åï¼æäº¤å岿¯ä¸æ¡ç´çº¿ï¼å¹²åå©è½
è¿è®©æå¼å§æèä¸ä¸ªé®é¢ï¼mergeårebaseå°åºç¨åªä¸ªï¼
| 维度 | merge | rebase |
|---|---|---|
| åå²è®°å½ | ä¿ç宿´åæ¯åå²ï¼æmerge commit | 线æ§åå²ï¼æ merge commit |
| å²çªå¤ç | 䏿¬¡æ§è§£å³ææå²çª | æ¯æ¬¡æäº¤é½å¯è½éè¦è§£å³å²çª |
| å®å ¨æ§ | 䏿¹ååå²ï¼ç»å¯¹å®å ¨ | 伿¹ååå²ï¼å ±äº«åæ¯æ ç¨ |
| éç¨åºæ¯ | åå¹¶åè½åæ¯å°main | æ´ç个人å¼å忝çæäº¤ |
| å¢éåä½ | éåå¤äººåä½ç忝åå¹¶ | éåä¸ªäººåæ¯åæ¥ææ°ä»£ç |
æ ¸å¿ååï¼æ°¸è¿ä¸è¦rebaseå·²ç»æ¨å°è¿ç¨ä¸å«äººæ£å¨ä½¿ç¨ç忝ãrebase伿¹åæäº¤åå²ï¼å¦æå«äººåºäºä½ çæ§æäº¤å¨å¼åï¼rebaseä¹åä»ä»¬ç代ç 就对ä¸ä¸äºãé»éæ³åâârebaseåªç¨äºä½ èªå·±çãè¿æ²¡è¢«å«äººæåç忝ã
çè§£äºmergeårebaseä¹åï¼æçGitä¸çè§è¢«å·æ°äºã忥æä¹åä¸ç´å¨ç¨æç¬¨çæ¹å¼å·¥ä½ï¼æåæ¯ãæ¹ä»£ç ãååmainãmergeãå 忝ã妿main卿å¼åæé´ææ´æ°ï¼mergeå°±ä¼äº§çå²çªï¼èæå¤çå²çªçæ¹å¼å°±æ¯è®åææ¹ã
å¦ä¼rebaseä¹åï¼æç工使µåæäºï¼æåæ¯ãæ¹ä»£ç ãå¼åæé´éæ¶git rebase mainæmainçææ°æ¹å¨åæ¥å°æç忝ä¸ãè¿æ ·æç忝å§ç»åºäºææ°çmain代ç ï¼åå¹¶çæ¶åå ä¹ä¸ä¼æå²çªãå³ä½¿æå²çªï¼ä¹æ¯å¨rebaseé¶æ®µåæäº¤éæ¥è§£å³çï¼æ¯ä¸æ¬¡æ§é¢å¯¹ä¸å¤§å¨å²çªæ¸
æ°å¾å¤ã
è¿æä¸ä¸ªè®©æç¸è§æ¨æçå½ä»¤æ¯git stashã以åæå¨feature忝䏿¹å°ä¸åï¼çªç¶éè¦åå°main修个紧æ¥bugï¼æçåæ³æ¯ææ¹å¨æ³¨éæç¶åå忝ãå¦äºstashä¹åï¼ä¸è¡å½ä»¤å°±è½æå·¥ä½åºçæ¹å¨æåèµ·æ¥ï¼åå®åæ¯å¤çå®äºæ
ågit stash popæ¢å¤ãè¿ç§å°å½ä»¤ç§¯æå¤äºï¼æçæåæ¯å®å®å¨å¨çã
æå¼å§ä¸»å¨å»ç ç©¶åç§Git工使µæ¨¡åã
ä»Git Flowå°Trunk-Basedï¼å·¥ä½æµéå
é£å 天ææä¸»æµçGit工使µé½ç ç©¶äºä¸éï¼åç°ä¸åçå¢éè§æ¨¡å项ç®ç±»åéåä¸åç工使µã
Git Flowæ¯æç»å ¸ç工使µï¼ç±Vincent Driessenå¨2010å¹´æåºã宿äºä¸ªåæ¯ç±»åï¼mainï¼ç产ï¼ãdevelopï¼å¼åï¼ãfeatureï¼åè½ï¼ãreleaseï¼åå¸ï¼ãhotfixï¼çä¿®å¤ï¼ãæµç¨å®åä½å¤æï¼éåææç¡®åå¸å¨æç项ç®ï¼æ¯å¦å®¢æ·ç«¯Appï¼ã
# Git Flowçå
¸åæµç¨
# 1. ä»developæfeature忝
git checkout develop
git checkout -b feature/new-payment
# 2. å¼å宿ååå¹¶ådevelop
git checkout develop
git merge --no-ff feature/new-payment
# 3. åå¤å叿¶ï¼ä»developærelease忝
git checkout -b release/1.2.0
# 4. releaseæµè¯éè¿ååå¹¶å°mainådevelop
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release 1.2.0"
git checkout develop
git merge --no-ff release/1.2.0
GitHub Flowæ´ç®æ´ï¼åªæmainåfeature忝ãæåæ¯ãå¼åãPRãåå¹¶ï¼å®äºãéåWebåºç¨åæç»é¨ç½²çå¢éã
# GitHub Flowï¼ç®åç´æ¥
git checkout main
git pull origin main
git checkout -b feature/dark-mode
# å¼åãæäº¤
git push origin feature/dark-mode
# åèµ·Pull Requestï¼Code Reviewéè¿ååå¹¶å°main
# èªå¨è§¦åCI/CDé¨ç½²
Trunk-Based Developmentææ¿è¿ï¼ææäººé½å¾mainä¸æäº¤ï¼é feature flagæ§å¶åè½å¼å ³ãéåå·¥ç¨è½å强çå¢éï¼é åCI/CDå®ç°é«é¢é¨ç½²ã
| 工使µ | 忝æ°é | 䏿é¾åº¦ | åå¸é度 | éç¨å¢é |
|---|---|---|---|---|
| Git Flow | 5ç±»åæ¯ | é« | æ ¢ï¼ærelease忝 | æåºå®åå¸å¨æçé¡¹ç® |
| GitHub Flow | 2ç±»åæ¯ | ä½ | å¿«ï¼åå¹¶å³é¨ç½² | Webåºç¨ãSaaS产å |
| Trunk-Based | 1个main | ä¸ | æå¿«ï¼æç»é¨ç½² | å·¥ç¨è½å强ãCIå®åç大å |
æä»¬å¢éäºåæ¥å·äººï¼åçWeb产åï¼GitHub Flowæåéãç®åã髿ãä¸å®¹æåºéã
使鿩GitHub Flowè¿æä¸ä¸ªåå ï¼å®åCI/CD天ç¶å¥åãæ¯æ¬¡PRåå¹¶å°mainï¼èªå¨è§¦åé¨ç½²æµæ°´çº¿ãä¸éè¦ä¸é¨çrelease忝ï¼ä¸éè¦äººå·¥æ è®°çæ¬å·ï¼é¤éè¦ætagï¼ãå¼åèå¥å¿«ï¼ä¸çº¿é¢çé«ï¼åé¦å¨æçãè¿å¯¹äºä¸ä¸ªæ£å¨å¿«éè¿ä»£çäº§åæ¥è¯´ï¼æ¯ä»ä¹é½éè¦ã
Git Flowçrelease忝æµç¨è½ç¶ä¸¥è°¨ï¼ä½å¯¹äºWebäº§åæ¥è¯´å¤ªéäºãä½ å¾ç»´æ¤develop忝ï¼è¿å¾å¨åå¸åærelease忝念è¯ï¼æµè¯å®åå¹¶å°mainådevelopä¸¤ä¸ªåæ¯ãå¦æä½ æ¯å¨åå¥½å æ¬¡çï¼å åæ¯ç®¡çå°±å æä¸å°æ¶é´ãèTrunk-Basedè½ç¶å¿«ï¼ä½è¦æ±å¢éæå¾å¼ºçèªå¨åæµè¯è½ååfeature flag管çè½åï¼æä»¬å½æ¶çå·¥ç¨åºç¡è®¾æ½è¿æä¸ä½ã
æä»¥éå䏿¯é"æå¥½"çï¼èæ¯é"æéåå½åå¢éè½å"çã
工使µéå建议ï¼ä¸è¦ç²ç®è¿½æ±"æä½³å®è·µ"ï¼éåå¢éè§æ¨¡å项ç®ç¹ç¹çææ¯æå¥½çãå°å¢éç¨GitHub Flowå°±å¤äºï¼å«ä¸æ¥å°±Git Flowæäºå±åæ¯ï¼å¤§åå·¥ç¨è½å强å¯ä»¥èèTrunk-Basedï¼ä½åææ¯CI/CDåèªå¨åæµè¯è¶³å¤å®åã
commitè§èï¼è®©åå²è®°å½ä¼è¯´è¯
ç ç©¶å®å·¥ä½æµï¼æååç°ä¸ä¸ªé®é¢ï¼æä»¬çcommit messageåå¾ä¹±ä¸å «ç³ãæå"fix bug"çï¼æå"update"çï¼çè³æäººç´æ¥åäºä¸ä¸ªå¥å·ã
# 以åæä»¬çcommit message
git commit -m "fix bug"
git commit -m "update"
git commit -m "..."
git commit -m "ç»äºæ¹å®äº"
# å¦äºAngularæäº¤è§èåçcommit message
git commit -m "feat(auth): æ°å¢å¾®ä¿¡æ«ç ç»å½åè½"
git commit -m "fix(payment): ä¿®å¤æ¯ä»éé¢è®¡ç®ç²¾åº¦ä¸¢å¤±é®é¢"
git commit -m "refactor(user): éæç¨æ·ä¿¡æ¯æ¥è¯¢é»è¾ï¼åå°3次DBè°ç¨"
git commit -m "docs(api): æ´æ°æ¯ä»æ¥å£ææ¡£ï¼è¡¥å
é误ç 说æ"
Angular commitè§èçæ ¸å¿ç»ææ¯<type>(<scope>): <subject>ï¼
彿¶æ¨è¡è¿ä¸ªè§èçæ¶åï¼é»åæ¯ææ³è±¡ç大ãæäººè§å¾"å个commit messageè¿è¦æ³å天太麻ç¦äº"ï¼æäººè¯´"æä¸ç´é½è¿ä¹å乿²¡åºè¿é®é¢"ã使å¨è§èææ¡£éæ¾äºä¸ä¸ªçå®çä¾åï¼æä¸æ¬¡çº¿ä¸æ¯ä»åºäºbugï¼æä»¬éè¦ä»æè¿ä¸¤å¨çæäº¤éæ¾åºæ¯åªæ¬¡æ¹å¨å¼å
¥çãç±äºcommit messageå
¨æ¯"update"å"fix bug"ï¼æä»¬ä¸å¾ä¸ä¸ä¸ªä¸ä¸ªç¹è¿å»çdiffï¼è±äºä¸¤ä¸ªå°æ¶æå®ä½å°é®é¢ã妿commit messageåçæ¯fix(payment): ä¿®æ¹éé¢è®¡ç®é»è¾æ¹ç¨Decimalï¼ä¸è¡git log --grep="payment"å°±è½æ¾å°ã
| åæ®µ | 说æ | 常ç¨å¼ |
|---|---|---|
| type | æäº¤ç±»å | featï¼æ°åè½ï¼ãfixï¼ä¿®å¤ï¼ãdocsï¼ææ¡£ï¼ãstyleï¼æ ¼å¼ï¼ãrefactorï¼éæï¼ãtestï¼æµè¯ï¼ãchoreï¼æå»º/å·¥å ·ï¼ |
| scope | å½±åèå´ | 模ååï¼å¦ authãpaymentãuser |
| subject | ç®çæè¿° | ä¸è¶ è¿50个å符ï¼ç¨ä¸ææè±æåå¯ï¼ä¸å å¥å· |
commit messageçä»·å¼ï¼å¥½çæäº¤ä¿¡æ¯æ¯ç»æªæ¥çèªå·±åå¢éççãåå¹´å线ä¸åºäºbugï¼ä½ éè¦ä»åå²è®°å½éå®ä½æ¯åªæ¬¡æäº¤å¼å ¥çï¼æ¸ æ°çcommit messageè½å¸®ä½ çä¸å ä¸ªå°æ¶ã
git log --oneline --grep="fix(payment)"ä¸è¡å½ä»¤å°±è½çåºæææ¯ä»ç¸å ³çä¿®å¤è®°å½ã
Git Hooksï¼è®©è§èèªå¨æ§è¡
è§èå好äºï¼ä½é 人èªè§æ¯ä¸è¡çãæ»æäººå¿è®°æåæ¯ãå¿è®°åè§èçcommit messageãè¿æ¶åGit Hooks就派ä¸ç¨åºäºã
Git Hooksæ¯Gitå¨ç¹å®äºä»¶åçæ¶èªå¨æ§è¡çèæ¬ï¼åå¨é¡¹ç®ç.git/hooksç®å½ä¸ã常ç¨çæpre-commitï¼æäº¤åæ£æ¥ï¼åcommit-msgï¼æäº¤ä¿¡æ¯æ ¡éªï¼ã
#!/bin/bash
# .git/hooks/commit-msg - æ ¡éªcommit messageæ ¼å¼
commit_regex='^(feat|fix|docs|style|refactor|test|chore)\(.+\): .{1,50}'
error_msg="ä½ çcommit messageä¸ç¬¦åè§èï¼æ ¼å¼ï¼type(scope): subject"
if ! grep -iqE "$commit_regex" "$1"; then
echo "$error_msg"
echo "示ä¾ï¼feat(auth): æ°å¢å¾®ä¿¡æ«ç ç»å½åè½"
exit 1
fi
ä½.git/hooksç®å½ä¸ä¼è¢«Git追踪ï¼å¢éå使¶æ²¡æ³å
±äº«ãæä»¥æä»¬ç¨äºhuskyè¿ä¸ªå·¥å
·ï¼æhooksæ¾å¨é¡¹ç®éï¼éè¿npmå®è£
åèªå¨çæï¼
# å®è£
husky
npm install husky --save-dev
npx husky init
# æ·»å pre-commité©åï¼æäº¤åè·lintï¼
echo "npm run lint" > .husky/pre-commit
# æ·»å commit-msgé©åï¼æ ¡éªæäº¤ä¿¡æ¯ï¼
echo "npx --no-install commitlint --edit \$1" > .husky/commit-msg
Hooksçæ ¸å¿ä»·å¼ï¼æè§èåæèªå¨æ£æ¥ï¼è䏿¯é å£å¤´çº¦å®ã代ç ä¸ç¬¦ålintè§åï¼æäº¤è¢«æ¦æªãcommit messageä¸åè§ï¼æäº¤è¢«æ¦æªãå¼åè ä¸éè¦è®°ä½ææè§èï¼Hooksä¼å¨å ³é®æ¶å»æéä½ ãè¿å°±æ¯"é²å设计"ââ让æ£ç¡®çäºæ 容æåï¼è®©é误çäºæ åä¸äºã
CIéæï¼æåä¸éé²çº¿
Hooksè½æ¦ä½æ¬å°çé®é¢ï¼ä½è¿ä¸å¤ãæäºäººçhookså¯è½æ²¡è£ ä¸ï¼æäºæ£æ¥éè¦å¨éæç¯å¢ä¸è·ãæä»¥æä»¬å¨GitLab CIéå äºä¸é宿´çæµæ°´çº¿ã
# .gitlab-ci.yml
stages:
- lint
- test
- build
- deploy
lint:
stage: lint
script:
- npm install
- npm run lint
- npm run type-check
rules:
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"
test:
stage: test
script:
- npm run test:unit
- npm run test:integration
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
build:
stage: build
script:
- docker build -t app:$CI_COMMIT_SHORT_SHA .
only:
- main
deploy:
stage: deploy
script:
- docker push registry.example.com/app:$CI_COMMIT_SHORT_SHA
- kubectl set image deployment/app app=registry.example.com/app:$CI_COMMIT_SHORT_SHA
only:
- main
when: manual
æ¯æ¬¡åèµ·Merge Requestï¼CIèªå¨è·lintåæµè¯ãæµè¯ä¸éè¿ï¼MRæ æ³åå¹¶ã代ç è¦ççä¸éäºï¼ä¼å¨MRè¯è®ºéæéãè¿ä¸å¥ä¸æ¥ï¼è´¨éåºæ¬æä¿éäºã
CIæµæ°´çº¿è¿è§£å³äºä¸ä¸ªä¹åä¸ç´å°æ°æä»¬çé®é¢ï¼ç¯å¢ä¸è´æ§ã以åç»å¸¸åºç°"ææ¬å°è½è·ä½CIè·ä¸è¿"çæ åµï¼åå å¯è½æ¯Nodeçæ¬ä¸åãä¾èµçæ¬ä¸ä¸è´ãç¯å¢åé缺失ãCIç¨Docker容å¨è·ï¼ç¯å¢å®å ¨ä¸è´ãæ¬å°è·ä¸è¿CIï¼é£å°±æ¯ä½ çæ¬å°ç¯å¢æé®é¢ï¼ä¸æ¯CIçé®é¢ãè¿é¼ç大家æä¾èµåç¯å¢é ç½®åè¿ä»£ç éï¼è䏿¯é "å£å¤´ä¼ 帮带"æ¥ç»´æ¤å¼åç¯å¢ã
æä»¬è¿å äºä¸ä¸ªæ¯è¾å®ç¨çCI jobï¼MRè¯è®ºéèªå¨å±ç¤ºå½åæ¹å¨ä¼å½±ååªäºAPI端ç¹ãéè¿éæåæè·¯ç±å®ä¹æä»¶ï¼å¯¹æ¯MRååçå·®å¼ï¼æåå½±åçæ¥å£ååºæ¥ãè¿æ ·æµè¯åäºå°±ç¥éè¿æ¬¡æ¹å¨éè¦éç¹åå½åªäºæ¥å£ï¼ä¸ç¨çã
| CIé¶æ®µ | æ£æ¥å 容 | å¤±è´¥åæ |
|---|---|---|
| lint | 代ç 飿 ¼ãç±»åæ£æ¥ | MRæ æ³åå¹¶ |
| test | åå æµè¯ãéææµè¯ | MRæ æ³åå¹¶ |
| build | Dockeréåæå»º | é¨ç½²é¶æ®µä¸æ§è¡ |
| deploy | é忍éãK8sæ´æ° | æå¨è§¦åï¼å¯åæ» |
ä¸å¨åï¼å¢éGitè§èææ¡£
å ¥èä¸å¨çæ¶åï¼ææè¿å 天ç踩åç»ååç ç©¶å¿å¾æ´çæäºä¸ä»½å¢éGitè§èææ¡£ã没æ³å°CTOçå®åç´æ¥è¯´ï¼"è¿ä¸ªä¸éï¼ä»¥åå¢éå°±æè¿ä¸ªæ¥ã"
è§èçæ ¸å¿å å®¹å ¶å®å°±å æ¡ï¼ææå®ä»¬åæäºé¡¹ç®READMEéçGit Workflowç« èï¼æ°äººå ¥è第ä¸ä»¶äºå°±æ¯è¯»è¿ä¸ªï¼
é¤äºåºæ¬æµç¨ï¼è§èéè¿å äºå æ¡"è¡æ³ªç»éª"ãæ¯å¦ï¼ä¸è¦å¨å¨äºä¸åäºç¹ä»¥åå并代ç å°mainââ妿åºé®é¢ä½ å¾å¨å¨æ«å çä¿®ã忝å¦ï¼åå¹¶MRåå æmainçææ°ä»£ç rebaseå°èªå·±ç忝ä¸ï¼ç¡®ä¿æ²¡æå²çªä¸CIå ¨ç»¿ââä¸è¦å¯å¸æäºGitLabçå¨çº¿å²çªè§£å³å·¥å ·ï¼æäºå²çªå®å¤çä¸äºã
è¿æä¸æ¡æ¯å
³äºhotfixçï¼çº¿ä¸ç´§æ¥bugä¿®å¤ç´æ¥ä»mainæhotfix/忝ï¼ä¿®å®ååå¹¶å°mainå¹¶ç«å³é¨ç½²ãä¸èµ°å¸¸è§çMR reviewæµç¨ï¼ä½è¦æ±äºåè¡¥ä¸ä¸ªpostmortemææ¡£ï¼è¯´æbugåå åä¿®å¤æ¹æ¡ãè¿æ¡è§èçèµ·å æ¯ææ¬¡çº¿ä¸æ¯ä»æäºï¼çMR reviewèµ°å®æµç¨å·²ç»è¿äºåååéï¼æå¤±äºä¸å°è®¢åã
# 1. 忝å½åï¼type/ç®çæè¿°
git checkout -b feature/user-avatar-upload
git checkout -b fix/payment-precision
# 2. commit messageï¼type(scope): subject
git commit -m "feat(auth): æ°å¢å¾®ä¿¡æ«ç ç»å½åè½"
# 3. å¼ååå
æåææ°ä»£ç
git checkout main
git pull origin main
git checkout -b feature/xxx
# 4. ä¸ªäººåæ¯åæ¥mainç¨rebaseï¼åå¹¶å°mainç¨merge
git checkout feature/xxx
git rebase main # 忥mainææ°ä»£ç
# 5. åå¹¶åç¡®ä¿CIéè¿
# åèµ·MRï¼çCI绿ç¯ï¼Code Reviewéè¿åååå¹¶
è§è䏿¯ç®çï¼æçææ¯ã好çGitè§è䏿¯ä¸ºäºéå¶å¼åè ï¼èæ¯è®©å¢éå使´é¡ºç ã彿æäººé½éµå¾ªåä¸å¥è§åæ¶ï¼ä½ ä¸éè¦çæµå«äººç忝å½åãä¸éè¦å¨æ··ä¹±çæäº¤åå²é大海æéãä¸éè¦æ å¿ä»£ç åå¹¶ååºé®é¢ãè§èéä½äºæ²éææ¬ï¼è®©å¢éæç²¾åæ¾å¨çæ£éè¦çäºæ ä¸ââå好代ç ã
å ¥è第ä¸å¨çGitè¡æ³ªå²ï¼è®©æä»"force pushç¸äºmain"çèé¸ï¼åæäºå¢éGitè§èçå¶å®è ãCTO忥å¨å¹´ä¼ä¸è¿æ¿è¿äºå¼äºä¸ªç©ç¬ï¼"badhopeå ¥è第ä¸å¤©å°±æmainæå´©äºï¼ä½ä»ä¹æ¯å¯ä¸ä¸ä¸ªæå´©æºç»éªåæå¢éè§èç人ã"
å°ä¸åå 大ç¬ãæä¹ç¬äºï¼ä½ç¬é带çé£å¤©çå°CTOåé®å·æ¶çå¿æä½æ¸ã
ä½ è¸©è¿ä»ä¹Gitçåï¼force pushãmergeå²çªãè¿æ¯rebase翻车ï¼è¯è®ºåºèèï¼è¯´åºæ¥å¤§å®¶å¼å¿ä¸ä¸ã
Aitishiku.com