
05 — 分支與合并怎么試新想法還不弄壞主線寫在前面這一章要解決什么寫到一半想試個新寫法又怕把能跑的版本改壞了——這就是分支要解決的問題。分支讓你復(fù)制出一條「平行宇宙」在里頭隨便試主線不受影響。試成了再「合并」回去試不成直接扔掉。但合并時如果兩邊都改了同一處Git 不會瞎猜會停下來讓你親手決定——這就是「沖突」。本章帶你第一次解決沖突。學(xué)完后你應(yīng)該能用大白話解釋分支是什么新建分支、切換分支、合并分支看懂git log --graph的分叉圖解決一次文本沖突知道什么時候該用分支讀者設(shè)定大一同學(xué)會基本工作流和撤銷還沒碰過團隊協(xié)作。1. 定位為什么要單開一章講分支1.1 一句話先記住分支 給某一次提交貼的張「便利貼」可以隨便撕、隨便貼。很多人以為分支是「復(fù)制整個項目文件夾」其實不是。分支就是一個名字比如feature/login指向某次提交。創(chuàng)建分支幾乎不占空間。1.2 沒有分支會怎樣場景沒有分支有分支想試新寫法直接改主線改壞了難回開個分支試壞了直接刪同時改兩塊功能互相覆蓋各開一條分支想保留「能跑的版本」不敢動主線就是能跑的1.3 生活里的類比你已經(jīng)會的分支對應(yīng)影印一份草稿再亂改分支但 Git 更省空間「另存為」副本分支但 Git 共用未改的部分平行宇宙設(shè)定在另一條時間線改主線不動游戲存檔點主線一個檔試錯一個檔1.4 本章內(nèi)容目標目標你能做到理解分支說清「分支是名字不是文件夾拷貝」操作建、切、并、刪分支看圖讀懂git log --graph的分叉解決沖突處理一次標記心態(tài)敢試因為不怕改壞2. 本質(zhì)分支到底是什么2.1 一張圖先建立感覺圖main和feature兩條線從同一次提交分叉最后合并成一個雙親節(jié)點。2.2 用白話拆開提交是歷史里的一個點像存檔。分支是給某個提交貼的「名字標簽」。HEAD是「你現(xiàn)在在哪條分支上」的指示牌。合并把兩條分支的改動匯成一條歷史。創(chuàng)建分支 貼一張新名字標簽不復(fù)制文件。2.3 兩種合并快進 vs 真合并情況結(jié)果一邊沒動過快進直接把分支指針挪過去不新建提交兩邊都改了真合并新建一個「合并提交」它有兩個父提交2.4 沖突是什么如果兩邊改了同一個文件的同一處Git 沒法自動決定要哪個就停下來讓你選。文件里會出現(xiàn)標記圖和之間是沖突的兩份版本分隔。沖突不是報錯是 Git 在說「這一處我?guī)湍阃O铝四銇矶ā埂?.5 幾條硬規(guī)矩規(guī)矩白話分支是名字不是文件夾拷貝創(chuàng)建幾乎不占空間切換分支前最好工作區(qū)干凈否則改動可能跟著飄過去合并沖突要手動解決Git 不會瞎猜刪分支刪的是名字提交可能還在別怕刪錯主線只合并「試成了」的分支保持主線穩(wěn)定2.6 新手最常踩的坑坑表現(xiàn)辦法一直在main上干活改壞了沒退路先開分支再試切換時工作區(qū)臟改動飄過來或報錯切換前status臟了就提交或藏起來沖突標記留在文件里提交了帶標記的代碼提交前搜索以為沖突是 Git 壞了慌著亂按沖突是正常的照著標記改就行3. 建議學(xué)習(xí)順序建分支 → 切過去改 → 切回主線 → 合并先試快進→ 故意制造沖突 → 解決 → 刪分支4. 動手準備mkdirlab-branchcdlab-branchgitinit-bmaingitconfig user.nameAda Examplegitconfig user.emailadaexample.comprintfbase\nf.txtgitaddf.txtgitcommit-minit: 基礎(chǔ)版本5. 跟著做一次完整分支實驗5.1 建分支并切過去gitbranch feature/hellogitswitch feature/hellogit branch 名字創(chuàng)建分支但不切過去git switch 名字切過去。也可以一步到位gitswitch-cfeature/hello-c是 create新建的意思。5.2 在分支上改printffeature line\nf.txtgitaddf.txtgitcommit-mfeat: 在分支上加一行5.3 切回主線也改一下gitswitch mainprintfmain line\nf.txtgitaddf.txtgitcommit-mfeat: 在主線加一行5.4 看分叉圖gitlog--oneline--graph--all* 399c46d feat: 在主線加一行 | * 744af9b feat: 在分支上加一行 |/ * a1819a3 init: 基礎(chǔ)版本怎么讀這張圖最下面a1819a3是共同起點往上分兩條線主線加了一行、分支加了一行/和\表示分叉5.5 合并這次會沖突gitmerge feature/hello-m合并 feature 分支Auto-merging f.txt CONFLICT (content): Merge conflict in f.txt Automatic merge failed; fix conflicts and then commit the result.白話翻譯兩邊都改了f.txtGit 自動合不了停下來等你定。5.6 看沖突文件catf.txtbase HEAD main line feature line feature/hello三段含義標記含義 HEAD當前分支main的版本開始分界線 feature/hello傳入分支的版本結(jié)束5.7 解決沖突你要做的就一件事把文件改成你最終想要的樣子然后刪掉所有、、標記。比如兩行都保留printfbase\nmain line\nfeature line\nf.txt然后告訴 Git「我改好了」gitaddf.txtgitcommit-m合并 feature/hello已解決沖突5.8 看合并后的圖gitlog--oneline--graph--all* 511c441 合并 feature/hello已解決沖突 |\ | * 744af9b feat: 在分支上加一行 * | 399c46d feat: 在主線加一行 |/ * a1819a3 init: 基礎(chǔ)版本怎么讀最上面511c441是合并提交它有兩條線匯入兩個父提交所以前面有|\。5.9 刪掉用完的分支gitbranch-dfeature/hello-d是 delete刪除已合并的分支。沒合并想強刪用-D。圖再看一遍——分叉、并行、合并成一個雙親節(jié)點。6. 命令按「用途」分組6.1 分支生命周期命令干什么git branch列出本地分支git branch 名字在當前提交創(chuàng)建分支git switch 名字切換到該分支git switch -c 名字新建并切換git branch -d 名字刪除已合并分支git branch -D 名字強制刪除6.2 合并命令干什么git merge 分支把該分支并入當前分支git merge --abort沖突中放棄合并回到合并前git log --oneline --graph --all看分叉圖6.3 解決沖突命令干什么git status看哪些文件沖突手動編輯改成最終樣子刪標記git add 文件標記「這個我改好了」git commit完成合并提交7. 對照表降低記憶負擔7.1 分支操作對照想干啥用什么看有哪些分支git branch建分支git branch 名字或git switch -c 名字切過去git switch 名字刪已合并git branch -d 名字強刪git branch -D 名字7.2 兩種合并對照情況結(jié)果圖上長啥樣一邊沒動快進只挪指針一條直線兩邊都動真合并新建合并提交出現(xiàn) 7.3 沖突三段標記標記是誰的版本 HEAD到當前分支到 名字傳入分支8. 安全習(xí)慣8.1 建議這樣做習(xí)慣原因切換前git status避免改動飄走主線只合并試成了的分支保持主線能跑合并后刪掉用完的分支減少噪音沖突解決后搜索標記別提交帶標記的代碼小步在分支上提交沖突面更小8.2 推薦工作流個人項目1. 在 main 上有個能跑的版本 2. git switch -c feature/新功能 3. 在分支上改、提交若干次 4. 切回 main 5. git merge feature/新功能 6. 有沖突就解決 7. 刪掉分支git branch -d feature/新功能9. 真實場景9.1 課程大作業(yè)分功能做主線保持「能跑的演示版」開feature/登錄頁、feature/排行榜各自試試成一個合并一個9.2 想試個新寫法怕改壞gitswitch-ctry/新算法# 隨便改# 不行就 git switch main 回去刪掉分支gitbranch-Dtry/新算法9.3 和同學(xué)協(xié)作之前各自在自己分支上改合并時如果沖突約好誰先合誰后合協(xié)作上傳是后面遠程章節(jié)9.4 不想合并只想看一眼分支gitswitch 別的分支# 看一眼gitswitch main切換分支會改你的工作區(qū)文件所以切換前最好干凈。10. 稍微多懂一點點可選分支是個文件在.git/refs/heads/下存的就是一個提交哈希。合并提交有兩個父提交所以圖上是|\??爝M合并不新建提交只是把指針挪過去。變基rebase是另一種合并思路進階章再講本章先會 merge。11. 小實驗請一定動手實驗甲快進合并建倉主線提交一次。建分支在分支提交一次。切回主線主線沒動過合并??磮D應(yīng)該是一條直線沒有|\。實驗乙制造并解決沖突按本章第 5 節(jié)走一遍。故意讓兩邊改同一行。合并、解決、提交??磮D出現(xiàn)|\。實驗丙放棄合并合并沖突后不解決直接git merge --abort。確認回到合并前狀態(tài)。通過標準能獨立制造并解決一次沖突不再害怕。12. 常見問題問 1分支占空間嗎幾乎不占。分支就是一個名字指向提交不復(fù)制文件。問 2我可以開很多分支嗎可以。但用完就刪免得亂。問 3沖突是 Git 壞了嗎不是是正常的。兩邊改了同一處Git 讓你定。問 4合并錯了能退嗎能。git reset --hard HEAD~1退一格小心會清工作區(qū)或git reset --mixed HEAD~1保留改動。問 5main和master有啥區(qū)別只是默認分支名不同。現(xiàn)代推薦main用git config --global init.defaultBranch main統(tǒng)一。問 6分支名怎么起好用feature/名字、fix/名字、try/名字這種前綴一眼知道是干嘛的。問 7合并一定要在main上嗎不一定。也可以把main合并進feature??茨阋裁葱Ч?。問 8沖突解決一半能停嗎能git merge --abort放棄這次合并。13. 總結(jié)、學(xué)習(xí)路線與思維升華13.1 這一章請記住的點記住什么分支本質(zhì)名字標簽不是文件夾拷貝創(chuàng)建git switch -c 名字合并git merge 分支沖突標記手動改后addcommit看圖git log --oneline --graph --all刪分支git branch -d 名字下一章遠程協(xié)作和別人的分支合并13.2 在整個系列中的位置01 認識 Git 02 三區(qū)模型 03 基本工作流 04 安全地撤銷 05 分支與合并 ← 當前 06 遠程協(xié)作 ……13.3 思維升華分支是「敢試」的底氣。主線永遠留著能跑的版本新想法開個分支試成了合并不成扔掉。沖突不是 Git 壞了是它在請你做決定。13.4 參考資料Pro Git 中文版 — 分支簡介Pro Git 中文版 — 分支的新建與合并git branch 說明git switch 說明git merge 說明本倉庫圖示署名assets/diagrams/ATTRIBUTION.md命令輸出樣例驗證環(huán)境Git 2.43.0演示作者信息為虛構(gòu)Ada Example adaexample.com。13.5 本章檢查清單能說清「分支是名字標簽不是拷貝文件夾」會用git switch -c新建并切換會用git merge合并讀懂git log --graph的分叉獨立解決過一次沖突提交前會搜索標記用完分支會刪敢試是分支給你的底氣。下一章我們把分支帶到「遠程」——和同學(xué)的分支合并。