最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Git分支管理之分支創(chuàng)建、切換和合并操作詳解

 更新時間:2026年06月26日 09:09:42   作者:say_fall  
本文會從分支的本質講起,把分支的前世今生畫成時間線,讓你徹底看懂 HEAD、分支指針、合并提交到底是什么,然后手把手教你創(chuàng)建、切換、合并、刪除分支等操作,希望對大家有所幫助

前言

如果讓你給 Git 的功能排個"驚艷榜",分支管理一定穩(wěn)坐第一。

但不少新手一提"分支"就頭大:HEAD 是什么?fast-forward 是啥?為什么合并會沖突?git stash 又是干啥的?

別慌。本篇就是來"治"這個的。我們從分支的本質講起,把分支的"前世今生"畫成時間線,讓你徹底看懂 HEAD、分支指針、合并提交到底是什么;然后手把手教你創(chuàng)建、切換、合并、刪除分支;再深入到合并沖突的真實解決過程;最后講 Bug 分支、stash 暫存、feature / release / hotfix 三大經典分支策略,以及企業(yè)級開發(fā)模型的引子(詳細模型我們留到第 5 篇專題展開)。

本節(jié)目標:讓你徹底玩轉 Git 分支管理。學完之后,你能像資深開發(fā)者一樣用分支隔離功能開發(fā)、用 stash 保護未完成代碼、用沖突解決流程搞定團隊合并,并對企業(yè)級分支模型有清晰的整體認知。

通過本文,你將掌握:

技能應用場景
從時間線角度理解分支本質看懂 Git 內部指針機制
熟練創(chuàng)建/切換/合并/刪除分支日常開發(fā)必備
掌握 fast-forward 與 --no-ff 模式合并寫出清晰的提交歷史
解決真實合并沖突團隊協作必踩的坑
用 git stash 暫存未完成工作緊急修復 Bug 不慌
理解 feature / release / hotfix 三大分支策略進階團隊協作

前置知識: 熟練掌握第 1 篇的本地倉庫操作(init、add、commit、log、reset、checkout)。本篇命令同樣在 user@localhost 虛擬環(huán)境下演示。

一、分支是什么:從時間線講起

要玩轉分支,先得搞清楚分支到底是什么。

1.1 一個生活中的類比

想象你正在寫一本書,主線版本寫到第 5 章。某天你想試試一個瘋狂的想法——把第 3 章結尾反轉到完全不同的方向。

最笨的辦法:把整本書復制一份,在副本上改。改得不好,主線還在;改得好,再合并回主線。

Git 的"分支"就是這個副本機制——而且它是幾乎零成本的。

1.2 Git 的分支本質

很多人以為 Git 分支是"復制整個項目目錄"。錯!

Git 的分支只是一個指向某個 commit 的可移動指針。

Git 倉庫的初始分支叫 master(現在很多項目改用 main),它指向你最新一次的提交。每提交一次,master 就往前移動一步。

看圖就懂:

時間線(master 一直往前走)

          C0 ── C1 ── C2 ── C3  ← master 指向最新
                            ↑
                          (HEAD)

  • 每一個 C0、C1… 是一次提交
  • master 是一個指針,永遠指向當前分支的最新提交
  • HEAD 是一個特殊指針,指向"你當前所在的分支"

1.3 創(chuàng)建分支后,時間線長這樣

當你在 C2 處創(chuàng)建了一個叫 dev 的分支:

時間線(master 和 dev 分叉)

                  master
                    ↓
          C0 ── C1 ── C2 ── C3
                            ↓
                           dev

實際工作流通常是這樣的:

                  master
                    ↓
          C0 ── C1 ── C2 ── C3 ── C5   ← master 繼續(xù)往前走
                \                ↑
                 \              (合并點)
                  C2'─ C4 ──────┘
                     ↑
                   dev

  • C2 處創(chuàng)建 dev 分支
  • dev 分支獨立提交了 C4
  • master 分支獨立提交了 C5
  • 最后把 dev 合并回 master

1.4 HEAD 到底是什么

HEAD 是一個指針文件,記錄在 .git/HEAD 里。它指向當前所在的分支

# 查看 HEAD 的指向
cat .git/HEAD
# 輸出:ref: refs/heads/master

這表示:當前所在分支是 master,HEAD 實際指向的是 master 這個指針。

切換分支時,HEAD 的指向也會改變。比如 git checkout dev 后,.git/HEAD 就會變成 ref: refs/heads/dev。

1.5 為什么 Git 分支"幾乎零成本"

別的版本控制系統(SVN、CVS)創(chuàng)建分支要把所有文件復制一份,耗時耗空間。

Git 呢?只創(chuàng)建一個新指針

# 在當前提交上創(chuàng)建一個叫 dev 的分支
git branch dev

# 實際就是創(chuàng)建了 .git/refs/heads/dev 文件
# 文件內容:當前 commit 的 SHA-1
cat .git/refs/heads/dev
# 輸出:abc1234567890abcdef1234567890abcdef123456

創(chuàng)建完沒有切換到 dev,要切換還需要 git checkout dev。

創(chuàng)建分支用 41 字節(jié)(commit id 的 SHA-1 長度)就夠了。這就是為什么 Git 在 Linux 這種千萬行代碼項目里也能毫秒級創(chuàng)建分支。

二、分支的創(chuàng)建與切換

理論講夠了,開始動手。

2.1 查看當前所有分支

git branch
# 輸出:
# * master
# 帶 * 號的是當前所在分支

-a 看所有分支(包括遠程分支):

git branch -a

2.2 創(chuàng)建分支

# 創(chuàng)建一個叫 dev 的分支(基于當前所在分支)
git branch dev

# 驗證
git branch
# 輸出:
#   dev
# * master
# (dev 已存在,但 HEAD 還在 master)

2.3 切換分支

git checkout 是切換分支的老牌命令(Git 2.23 之前唯一方式):

git checkout dev

# 驗證
git branch
# 輸出:
# * dev
#   master
# (* 號跳到了 dev)

注意:切換分支前要保證當前分支的工作區(qū)是干凈的(沒有未提交的改動),否則 Git 會拒絕切換,或者把改動"帶"到新分支。

2.4 創(chuàng)建并切換(最常用)

99% 的場景下,你要的是"創(chuàng)建新分支 + 立即切過去"。一條命令搞定

# 老語法
git checkout -b dev

# 新語法(Git 2.23+,更清晰)
git switch -c dev

輸出:

Switched to a new branch 'dev'

git switch 是 Git 2.23 引入的新命令,專門做"切換"這件事(git checkout 身兼多職容易混淆)。switch 讓命令語義更清晰。新項目建議用 switch。

2.5 在指定 commit 上創(chuàng)建分支

# 基于某個 commit id 創(chuàng)建分支
git branch <branch-name> <commit-id>

# 基于遠程分支創(chuàng)建本地分支
git branch <local-branch> origin/<remote-branch>

2.6 刪除分支

# 刪除已合并的分支(-d 是 --delete 的簡寫)
git branch -d dev

# 強制刪除(即使沒合并也刪,慎用?。?
git branch -D dev

-D 大寫是強制刪除,可能丟失未合并的提交。永遠不要在你不熟悉的分支上用 -D。

2.7 實戰(zhàn)演練

# 1. 看現在在哪
git branch
# * master

# 2. 創(chuàng)建并切到 dev
git checkout -b dev
# Switched to a new branch 'dev'

# 3. 在 dev 上做改動
echo "這是 dev 分支的修改" >> ReadMe
git add ReadMe
git commit -m "dev: 添加 dev 分支說明"

# 4. 切回 master
git checkout master
# Switched to branch 'master'

# 5. 看 ReadMe 的內容
cat ReadMe
# (dev 分支的修改不見了!因為它在 dev 分支上)

# 6. 把 dev 合并回 master
git merge dev
# 輸出(fast-forward 模式):
# Updating abc1234..def5678
# Fast-forward
#  ReadMe | 1 +
#  1 file changed, 1 insertion(+)

# 7. dev 分支可以刪了
git branch -d dev

到這里你已經玩過分支的"創(chuàng)建 → 切換 → 提交 → 合并 → 刪除"全流程。下一節(jié)我們深入看合并模式。

三、分支合并:fast-forward 模式

合并分支用 git merge 命令。但合并方式分兩種:fast-forward(快進)和 --no-ff(非快進)。

3.1 什么是 fast-forward

當 master 分支在 dev 創(chuàng)建后沒有任何新的提交,dev 分支順著 master 走,合并時直接"快進"指針到 dev 最新 commit。不會產生新的合并提交

時間線:

合并前:
                master
                  ↓
C0 ── C1 ── C2 ── C3
            \
             C2'─ C4
                 ↑
                dev

合并后(fast-forward):
                master, dev
                    ↓
C0 ── C1 ── C2 ── C3 ── C4

實際命令:

# 在 master 上執(zhí)行
git merge dev
# 輸出:
# Updating abc1234..def5678
# Fast-forward
#  ReadMe | 1 +
#  1 file changed, 1 insertion(+)

注意 “Fast-forward” 這個詞——它告訴我們這次是直接移動 master 指針到 C4,沒有產生新 commit。

fast-forward 是 Git 合并的"最優(yōu)解"——歷史是一條直線,沒有多余的合并節(jié)點,干凈利落。

3.2 實際例子

# 準備工作
mkdir -p /home/user/test/merge-test
cd /home/user/test/merge-test
git init
echo "v1" > ReadMe
git add .
git commit -m "v1"

# 創(chuàng)建 dev 分支
git checkout -b dev
echo "v2 in dev" >> ReadMe
git add .
git commit -m "v2 in dev"

# 切回 master,合并
git checkout master
git merge dev
# Fast-forward
#  ReadMe | 1 +
#  1 file changed, 1 insertion(+)

# 查看日志
git log --pretty=oneline
# def5678 (HEAD -> master, dev) v2 in dev
# cff9d1e v1
# 注意:master 和 dev 都指向同一個 commit

3.3 什么時候不會 fast-forward

當 master 在 dev 之后又有新提交時,無法 fast-forward??磮D:

合并前:
                 C0 ── C1 ── C2 ── C3  ← master
                            \
                             C2'─ C4
                                  ↑
                                 dev

這種結構沒辦法直接把 master 移到 C4(因為會丟掉 C3)。Git 會做三方合并,產生一個新的合并提交

合并后(三方合并):
                 C0 ── C1 ── C2 ── C3 ── C5 (merge commit)  ← master
                            \                /
                             C2'─ C4 ───────
                                  ↑
                                 dev

三方合并需要你寫合并提交信息(Git 會彈出編輯器)。可以加 -m "xxx" 直接寫。

四、--no-ff 模式合并:保留分支歷史

雖然 fast-forward 看起來很完美,但它有個小缺點分不清哪些提交是哪個分支做的

4.1 為什么需要 --no-ff

看下面這個歷史:

Fast-forward 后的歷史(看不出來分叉過):

C0 ── C1 ── C2 ── C3 ── C4

我完全看不出"哪些提交是在 dev 分支上做的"。功能分支被"抹平"了。

而用 --no-ff

--no-ff 合并后的歷史(能看出分叉):

C0 ── C1 ── C2 ── C3 ── C5 (merge commit)
            \                /
             C2'─ C4 ───────

C4 是在 dev 分支上做的,C5 是合并提交——一目了然。

4.2 怎么用 --no-ff

# 強制使用非 fast-forward 合并
git merge --no-ff -m "合并 dev 分支" dev

輸出:

Merge made by the 'recursive' strategy.
 ReadMe | 1 +
 1 file changed, 1 insertion(+)

注意:這次是 “Merge made by the ‘recursive’ strategy”,不是 Fast-forward,產生了新的 merge commit。

4.3 什么時候用 --no-ff

場景推薦模式
個人小項目 / 臨時分支fast-forward(默認)
團隊協作的功能分支–no-ff(強烈推薦)
上線分支 / 長期維護分支–no-ff
簡單的本地實驗fast-forward

企業(yè)開發(fā)中,功能分支合并幾乎都用 --no-ff。這樣歷史里能清晰看到"哪些功能是哪個分支做的",對后期維護和代碼審查幫助極大。

4.4 查看分支圖:git log --graph

看分支歷史結構的最強工具:

# 圖形化顯示
git log --graph --pretty=oneline --abbrev-commit

# 加上 --all 看所有分支
git log --graph --pretty=oneline --abbrev-commit --all

輸出類似:

*   c123456 (HEAD -> master) Merge branch 'dev'
|\
| * d789abc (dev) v2 in dev
|/
* a456789 v1

這個圖清晰顯示:master 和 dev 在 v1 后分叉,dev 提交了 v2,master 又合并了 dev。

建議把這條命令設個別名:

git config --global alias.lg "log --graph --pretty=oneline --abbrev-commit --all"

以后直接 git lg 就能看漂亮的分支圖。

五、?? 合并沖突:原理與解決

合并最讓人頭疼的就是沖突(Conflict)。但理解了原理,解決起來其實很簡單。

5.1 什么情況下會沖突

當兩個分支修改了同一個文件的同一行,Git 沒辦法自動判斷保留誰的內容,就會觸發(fā)沖突。

舉個例子:

# 1. 在 master 上改 ReadMe
git checkout master
echo "hello master" > ReadMe
git add .
git commit -m "master: 改 ReadMe"

# 2. 切到 dev 改同一行
git checkout dev
echo "hello dev" > ReadMe
git add .
git commit -m "dev: 改 ReadMe"

# 3. 切回 master 合并 dev
git checkout master
git merge dev
# 輸出:
# Auto-merging ReadMe
# CONFLICT (content): Merge conflict in ReadMe
# Automatic merge failed; fix conflicts and then commit the result.

出現 CONFLICT 就是沖突了。

5.2 看沖突文件

打開沖突文件(這里是 ReadMe),你會看到這樣的"奇怪"內容:

<<<<<<< HEAD
hello master
=======
hello dev
>>>>>>> dev

這段標記的含義:

  • <<<<<<< HEAD:當前分支(master)的內容
  • =======:分隔符
  • >>>>>>> dev:要合并過來的分支(dev)的內容

5.3 解決沖突

三步走:

① 手動編輯文件

保留你想要的內容(或者兩個都保留,或合并成新的內容):

# 編輯后:
hello master and dev

② 標記解決沖突

git add ReadMe

③ 完成合并

git commit -m "解決 ReadMe 合并沖突"

git add 不是"添加文件",在合并場景下它的意思是"我已解決沖突,標記這個文件為已解決"。

5.4 驗證沖突解決完沒

git status 會告訴你還有沒有未解決的沖突:

git status
# 輸出(未解決):
# Unmerged paths:
#   (use "git add <file>..." to mark resolution)
#         both modified:   ReadMe
# 
# 輸出(已解決):
# Changes to be committed:
#         modified:   ReadMe

看到 “Unmerged paths” 就是沒解決完。

5.5 取消合并

如果沖突搞砸了想放棄合并:

git merge --abort

這條命令會回退到合并前的狀態(tài),相當于"撤銷合并"。

5.6 用工具解決沖突

手動改文件太累?很多 IDE/編輯器有沖突解決工具:

  • VS Code:內置沖突解決器,左邊選 ours / theirs,右邊實時預覽
  • IntelliJ IDEA:三欄布局(base / ours / theirs)
  • Beyond Compare:專業(yè)的 diff 工具
  • Meld:免費跨平臺 diff 工具

團隊規(guī)模大了,強烈建議團隊成員用同一種沖突解決工具,避免風格不一致。

5.7 實戰(zhàn)示例:完整的沖突解決流程

# 假設沖突發(fā)生
git merge dev
# CONFLICT 提示

# 1. 看哪些文件沖突
git status
# Unmerged paths: ReadMe

# 2. 編輯 ReadMe(保留兩個版本)
vim ReadMe
# 改成你想要的內容,刪除 <<<<<<< ======= >>>>>>> 標記

# 3. 標記解決
git add ReadMe

# 4. 查狀態(tài)(應該沒有 Unmerged paths 了)
git status
# Changes to be committed: ReadMe

# 5. 完成合并
git commit -m "merge dev: 解決 ReadMe 沖突"

# 6. 驗證
git log --graph --pretty=oneline --abbrev-commit
# *   c123456 (HEAD -> master) merge dev: 解決 ReadMe 沖突
# |\
# | * d789abc (dev) dev: 改 ReadMe
# |/
# * a456789 master: 改 ReadMe

完美!沖突解決后,分支歷史清晰可讀。

六、Bug 分支與 stash 暫存

實際開發(fā)中,正在寫一個功能寫到一半,突然發(fā)現線上有 Bug 要立刻修——這種場景太常見了。怎么辦?

6.1 場景重現

# 1. 你正在 dev 分支開發(fā)一個"用戶登錄"功能,寫到一半
git checkout -b dev
echo "登錄功能代碼" > login.py
git add login.py
git commit -m "feat: 登錄功能 - 1"

echo "登錄功能代碼 - 2" >> login.py
# (注意:這里沒 commit,因為還沒寫完?。?

現在老板突然說:線上付款功能有 Bug,立刻修!

不能

  • 直接 git checkout master 切分支(會帶著未提交的文件)
  • git commit 把沒寫完的代碼提交了(污染歷史)

正確做法:用 git stash 暫存起來。

6.2 git stash 暫存

# 把當前工作區(qū)和暫存區(qū)的改動"打包"起來
git stash

# 輸出:
# Saved working directory and index state WIP on dev: abc1234 feat: 登錄功能 - 1

stash 本質是把改動保存到一個棧結構里,工作區(qū)瞬間變成"上次 commit 的干凈狀態(tài)"。

現在你可以放心切換分支修 Bug 了:

# 2. 切到主分支修 Bug
git checkout master

# 3. 創(chuàng)建 bugfix 分支
git checkout -b bugfix-001

# 4. 修復 Bug 并提交
echo "付款 Bug 修復" > pay.py
git add pay.py
git commit -m "fix: 修復付款 Bug"

# 5. 切回 master 合并 bugfix
git checkout master
git merge --no-ff -m "merge bugfix-001" bugfix-001

# 6. 刪除 bugfix 分支
git branch -d bugfix-001

修完 Bug,回到 dev 分支繼續(xù)寫你的登錄功能

# 7. 切回 dev 分支
git checkout dev

# 8. 把暫存的改動"恢復"出來
git stash pop

git stash pop 會把最新的 stash 恢復到工作區(qū),并從 stash 棧里刪除。

6.3 stash 常用命令

# 暫存當前改動(不帶消息)
git stash

# 暫存并加消息(推薦,方便查找)
git stash push -m "修復登錄功能寫到一半"

# 查看所有 stash
git stash list

# 恢復最新 stash(不刪除 stash)
git stash apply

# 恢復最新 stash(刪除 stash,等價于 apply + drop)
git stash pop

# 恢復指定 stash
git stash apply stash@{0}    # 恢復第 1 個
git stash apply stash@{1}    # 恢復第 2 個

# 刪除指定 stash
git stash drop stash@{0}

# 清空所有 stash
git stash clear

6.4 多個 stash 的管理

git stash push -m "改了一半的登錄功能"
git stash push -m "性能優(yōu)化草稿"
git stash push -m "UI 重構中"

git stash list
# stash@{0}: On dev: UI 重構中
# stash@{1}: On dev: 性能優(yōu)化草稿
# stash@{2}: On dev: 改了一半的登錄功能

stash 是個棧(LIFO:后進先出):

git stash pop   # 恢復 stash@{0}(UI 重構中)
git stash pop   # 恢復 stash@{1}(性能優(yōu)化草稿)
git stash pop   # 恢復 stash@{2}(改了一半的登錄功能)

6.5 暫存未追蹤的文件

默認 git stash 不暫存未追蹤的文件(新創(chuàng)建但沒 add 的):

echo "新文件" > new.txt  # 創(chuàng)建新文件,沒 add
git stash
# 暫存的是已追蹤文件的改動,new.txt 不會暫存

想暫存未追蹤文件,加 -u

git stash -u
# 或
git stash push -u -m "包含新文件"

6.6 stash 實戰(zhàn)工作流

# 1. 當前在 dev 分支,工作區(qū)有未提交的改動
git status
# modified: login.py

# 2. 老板緊急派活,先把當前改動暫存
git stash push -m "登錄功能 - 未完成"

# 3. 切到 hotfix 分支修緊急 Bug
git checkout master
git checkout -b hotfix
# ... 修 Bug、提交、合并、刪除分支 ...

# 4. 回到 dev 分支
git checkout dev

# 5. 恢復之前的改動
git stash pop

這是企業(yè)里每天都在發(fā)生的工作流。git stash 就是你的"工作區(qū)保險箱"。

七、分支管理策略:feature / release / hotfix

前面我們學的是"操作",現在講"策略"——一個團隊應該怎么用分支。

7.1 三大經典分支

分支類型作用來源歸宿生命周期
feature開發(fā)新功能developdevelop功能完成即刪
release發(fā)布前的穩(wěn)定分支developmaster + develop發(fā)布完即刪
hotfix緊急修復線上 Bugmastermaster + develop修完即刪

7.2 feature(功能分支)

場景:開發(fā)一個新功能。

# 從 develop 創(chuàng)建 feature 分支
git checkout develop
git checkout -b feature/user-login

# 開發(fā)...
git add .
git commit -m "feat: 用戶登錄"

# 完成后合并回 develop
git checkout develop
git merge --no-ff -m "merge feature/user-login" feature/user-login

# 刪除 feature 分支
git branch -d feature/user-login

feature 分支通常一個人用(避免沖突),完成后合并回 develop。

7.3 release(預發(fā)布分支)

場景:要發(fā)版了,做最后的測試和 Bug 修復。

# 從 develop 創(chuàng)建 release 分支
git checkout develop
git checkout -b release/v1.0.0

# 測試 + 修小 Bug
git commit -m "fix: 修復測試發(fā)現的 Bug"

# 測試通過,發(fā)布到 master
git checkout master
git merge --no-ff -m "release v1.0.0" release/v1.0.0
git tag v1.0.0  # 打 tag 標記版本

# 同步回 develop
git checkout develop
git merge --no-ff -m "merge release/v1.0.0 back to develop" release/v1.0.0

# 刪除 release 分支
git branch -d release/v1.0.0

為什么要同步回 develop?因為 release 分支可能修了 Bug,develop 也要拿到這些修復。

7.4 hotfix(緊急修復分支)

場景:線上版本出問題了,要立刻修。

# 從 master 創(chuàng)建 hotfix 分支
git checkout master
git checkout -b hotfix/pay-bug

# 修復 Bug
git add .
git commit -m "fix: 緊急修復付款 Bug"

# 修復完成,合并到 master
git checkout master
git merge --no-ff -m "hotfix pay-bug" hotfix/pay-bug
git tag v1.0.1  # 升級版本號

# 同步到 develop
git checkout develop
git merge --no-ff -m "merge hotfix/pay-bug" hotfix/pay-bug

# 刪除 hotfix 分支
git branch -d hotfix/pay-bug

hotfix 只修緊急的、能快速解決的 Bug。復雜問題應該走 feature 分支完整修復。

7.5 分支命名規(guī)范

好命名 = 好維護:

類型命名示例
功能分支feature/user-login、feature/shopping-cart
預發(fā)布分支release/v1.0.0、release/2024-q3
緊急修復hotfix/pay-bug、hotfix/crash-2024-09
個人開發(fā)dev/<your-name>/xxx

八、企業(yè)級開發(fā)模型:引子

你以為 feature / release / hotfix 就是全部了?不,這是經典 Git Flow 模型的核心。

一個完整的企業(yè)級開發(fā)模型遠不止這三個分支。它涉及:

  • 長期分支 vs 短期分支的搭配
  • 環(huán)境對應(開發(fā) / 測試 / 預發(fā)布 / 正式)
  • 角色分工(開發(fā) / 測試 / 運維 / 技術經理)
  • 發(fā)版節(jié)奏(每周 / 每月 / 緊急)
  • 回滾機制(出問題了怎么秒級回滾)

本節(jié)限于篇幅只講 feature / release / hotfix 三大基礎策略的單獨使用。完整的企業(yè)級開發(fā)模型(Git Flow / GitHub Flow / GitLab Flow)將在第 5 篇《企業(yè)級 Git 開發(fā)模型:從小作坊到工業(yè)級規(guī)范》 里專題展開。

到那里我們會看到:

  • 一個 10 人團隊怎么用 5 種分支協作
  • 不同公司為什么選不同的模型
  • 大廠的真實發(fā)版流程長什么樣
  • 怎么把 Git 用成"生產線"而不是"備份工具"

九、分支管理實操:完整工作流演示

把這一篇的所有知識點串起來,做一個完整的"個人開發(fā)工作流"演示。

任務:在 master 上開發(fā)"登錄功能",用 dev 隔離,用 stash 應對緊急情況。

# 1. 準備工作
mkdir -p /home/user/test/branch-workflow
cd /home/user/test/branch-workflow
git init
echo "v1" > app.py
git add .
git commit -m "init: 項目初始化"

# 2. 創(chuàng)建并切到 dev 分支
git checkout -b dev

# 3. 在 dev 上開發(fā)登錄功能
echo "def login(): pass" > login.py
git add login.py
git commit -m "feat(login): 添加登錄函數"

# 4. 突然老板讓修付款 Bug
# 把當前未提交的改動暫存(假設我們正在改 login.py)
echo "def login_v2(): pass" >> login.py
git stash push -m "login v2 寫到一半"

# 5. 切到 master 修付款 Bug
git checkout master
git checkout -b hotfix/pay-bug
echo "def pay(): fix" > pay.py
git add pay.py
git commit -m "hotfix(pay): 修復付款 Bug"

# 6. 合并回 master 并打 tag
git checkout master
git merge --no-ff -m "merge hotfix/pay-bug" hotfix/pay-bug
git tag v1.0.1
git branch -d hotfix/pay-bug

# 7. 回到 dev 繼續(xù)開發(fā)
git checkout dev
git stash pop   # 恢復 login v2 的改動

# 8. 完成登錄功能
git add login.py
git commit -m "feat(login): 完善登錄功能"

# 9. 合并到 master
git checkout master
git merge --no-ff -m "merge dev" dev
git tag v1.1.0

# 10. 刪除 dev 分支
git branch -d dev

# 11. 看完整歷史
git log --graph --pretty=oneline --abbrev-commit --all
# *   d789abc (HEAD -> master, tag: v1.1.0) merge dev
# |\
# | * c456def (tag: v1.0.1) hotfix(pay): 修復付款 Bug
# |/
# * b123456 init: 項目初始化

跑一遍這個流程,你對分支的"創(chuàng)建 → 切換 → 暫存 → 合并 → 刪除 → 標簽"就有完整感覺了。

十、本節(jié)常見問題解答

挑了 5 個跟分支管理最相關的問題,逐一解答。

為什么有人的 Git 終端有顏色?

答:配置顏色顯示。

Git 默認在某些終端會顯示顏色幫助區(qū)分。要開啟/關閉:

# 開啟顏色(推薦)
git config --global color.ui auto

# 關閉顏色
git config --global color.ui false

auto 模式:輸出到終端時顯示顏色,輸出到文件或管道時不顯示,最智能。

顏色不是"花里胡哨",是減少誤操作的關鍵。比如紅色的 deleted 比黑白文字警告更醒目。

什么是--no-ff模式合并?

答:保留分支歷史的合并方式。

git merge --no-ff 即使能 fast-forward,也強制創(chuàng)建合并提交,讓歷史能看出"哪些提交是哪個分支做的"。

# 不管能不能 fast-forward,都產生 merge commit
git merge --no-ff -m "merge feature/login" feature/login

團隊開發(fā)的功能分支強烈建議用 --no-ff。這樣 PR 評審、回溯功能、查 Bug 都很方便。

git stash pop多個 stash 會怎樣?

答:按 LIFO(后進先出)順序恢復。

git stash 把當前工作區(qū)"打包"暫存起來,git stash pop 把最新的 stash 恢復出來。多個 stash 會按棧結構組織:

git stash       # 暫存當前
git stash       # 暫存第二個
git stash list  # 查看所有 stash
git stash pop   # 恢復最新(即第二個)
git stash pop   # 恢復最早(即第一個)

stash 不是長期存儲方案。stash 默認可能 30 天后被清理。重要的代碼一定要 commit 提交,不能依賴 stash。

git stash和git stash push有什么區(qū)別?

答:幾乎沒有區(qū)別。

git stashgit stash push 的簡寫(Git 2.13+ 引入)。git stash push 更明確,支持更多參數:

# 等價
git stash
git stash push

# 推 stash 時附加信息
git stash push -m "修復登錄bug"

推薦用 git stash push -m "說明",給自己和別人留個上下文。

怎么判斷合并沖突有沒有解決完?

答:用 git status 看是否有 unmerged 標記。

沖突時 git status 會顯示:

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   file.txt

解決完沖突后 git add 標記解決,再 git status 就看不到 Unmerged paths 了。

解決沖突后一定要仔細看 diff!兩個分支的修改可能都"看起來對",但合并后邏輯可能錯。提交前用 IDE 走讀一遍。

十一、實戰(zhàn)練習:分支管理"五連擊"

來練 5 個連續(xù)動作,體驗真實開發(fā)場景。

任務:

  1. 創(chuàng)建一個叫 git-branch-practice 的倉庫,提交一個 app.py(內容任意)
  2. 創(chuàng)建 feature/pay 分支,加一個 pay.py 函數并提交
  3. 切回 master,創(chuàng)建 feature/login 分支
  4. feature/loginapp.py(加一行 import),切回 master 也改 app.py(加一行注釋)
  5. feature/login 合并到 master,解決沖突,合并 feature/pay 驗證 fast-forward
  6. 刪除所有臨時分支,用 git log --graph 看歷史

參考答案:

# 1. 初始化
mkdir -p /home/user/test/git-branch-practice
cd /home/user/test/git-branch-practice
git init
echo "print('hello')" > app.py
git add .
git commit -m "init: app.py"

# 2. feature/pay
git checkout -b feature/pay
echo "def pay(): pass" > pay.py
git add pay.py
git commit -m "feat(pay): 添加支付函數"

# 3. feature/login
git checkout master
git checkout -b feature/login
echo "import os" >> app.py
git add app.py
git commit -m "feat(login): 添加 os 導入"

# 4. 回到 master 也改 app.py
git checkout master
echo "# 入口文件" >> app.py
git add app.py
git commit -m "docs: 添加 app.py 注釋"

# 5. 合并 feature/login(會有沖突)
git merge feature/login
# CONFLICT 提示

# 編輯 app.py 解決沖突(保留兩邊的修改):
# print('hello')
# # 入口文件
# import os
git add app.py
git commit -m "merge feature/login: 解決沖突"

# 6. 合并 feature/pay(fast-forward)
git merge feature/pay
# Fast-forward
#  pay.py | 1 +
#  1 file changed, 1 insertion(+)

# 7. 刪除分支
git branch -d feature/login
git branch -d feature/pay

# 8. 看歷史
git log --graph --pretty=oneline --abbrev-commit --all

跑完這五步,你對分支管理就有"肌肉記憶"了。

十二、關鍵命令速查表

命令作用
git branch查看本地分支
git branch -a查看所有分支(含遠程)
git branch <name>創(chuàng)建分支
git branch -d <name>刪除已合并的分支
git branch -D <name>強制刪除分支
git checkout <name>切換分支(老語法)
git checkout -b <name>創(chuàng)建并切換分支
git switch <name>切換分支(新語法)
git switch -c <name>創(chuàng)建并切換分支
git merge <name>合并指定分支到當前分支
git merge --no-ff <name>非 fast-forward 合并
git merge --abort取消合并
git stash暫存當前改動
git stash push -m "..."暫存并加消息
git stash list查看所有 stash
git stash pop恢復并刪除最新 stash
git stash apply恢復但不刪除
git stash drop刪除指定 stash
git tag <name>打 tag
git log --graph --all圖形化看分支歷史

十三、幾個思考題

學完本文,來試試回答這些問題:

fast-forward 合并和 --no-ff 合并的本質區(qū)別是什么?

答:是否產生新的 merge commit。

  • fast-forward:當被合并的分支是當前分支的直接祖先時,Git 直接把當前分支指針移動到被合并分支的最新 commit,不產生新 commit
  • –no-ff:強制產生一個新的 merge commit,把兩條分支的歷史連接起來。

選擇建議:功能分支合并用 --no-ff(保留分支歷史),簡單同步用 fast-forward(保持歷史干凈)。

git log --graph 時,fast-forward 是一條直線,–no-ff 是一個"分叉再合并"的 Y 字形。

stash 后忘了 stash 列表里有什么,怎么辦?

答:用 git stash list + git stash show

# 1. 看所有 stash
git stash list
# stash@{0}: On dev: 改了一半的登錄功能
# stash@{1}: On dev: 性能優(yōu)化草稿

# 2. 看某個 stash 的內容(默認只看文件改動概覽)
git stash show stash@{0}

# 3. 看完整 diff
git stash show -p stash@{0}

如果 stash 內容太多忘了是什么,用 git stash show -p 看 diff??吹讲徽J識的代碼,別亂 pop,先開新分支驗證。

stash 不是 commit,沒有 message 也能存。養(yǎng)成 git stash push -m "說明" 的習慣,一個月后看也認得。

刪除分支前,怎么確認這個分支的工作已經合并了?

答:先看分支列表,再看 merged 列表。

# 1. 看所有分支
git branch -a

# 2. 看哪些分支已合并到當前分支
git branch --merged

# 3. 看哪些分支**未**合并
git branch --no-merged

--no-merged 列出的分支千萬別 -d,要用 -D 強制刪(且必須確認分支上的工作不要了)。

長期不清理的"僵尸分支"會讓 git branch 列表很亂。定期(比如每兩周)review 一次 merged / no-merged 列表。

合并沖突解決到一半,想放棄怎么辦?

答:git merge --abort(合并中)或 git rebase --abort(rebase 中)。

# 合并沖突中放棄合并
git merge --abort

# rebase 沖突中放棄
git rebase --abort

執(zhí)行后,工作區(qū)會恢復到合并/rebase 之前的狀態(tài),相當于"撤銷這次操作"。

 比 --abort 更狠的是 git reset --hard HEAD,但那會丟失所有未提交的改動。--abort 是更安全的選擇。

怎么刪除遠程已不存在的遠程跟蹤分支?

答:git remote prune origin。

# 刪除遠程已刪除但本地還殘留的遠程跟蹤分支
git remote prune origin

# 或者用 fetch 時自動清理
git fetch --prune origin
# 簡寫
git fetch -p

這條命令會同步遠程狀態(tài),把本地那些"遠程已經刪了但本地還留著"的遠程跟蹤分支清理掉。

遠程分支積累多了 git branch -a 會很難看。每個工作日開始前 fetch -p 一下是好習慣。

以上就是Git分支管理之分支創(chuàng)建、切換和合并操作詳解的詳細內容,更多關于Git分支操作的資料請關注腳本之家其它相關文章!

相關文章

  • 關于圖片存儲格式的整理(JPEG格式介紹)

    關于圖片存儲格式的整理(JPEG格式介紹)

    這篇文章主要介紹了關于圖片存儲格式的整理(JPEG),需要的朋友可以參考下
    2016-01-01
  • Postman 使用指南及小技巧

    Postman 使用指南及小技巧

    Postman 簡化了構建 API 的每個步驟,并簡化了協作,這樣就可以更快地創(chuàng)建 API。接下來通過本文給大家介紹Postman 使用指南及小技巧,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • 使用let's?encrypt申請免費的SSL證書

    使用let's?encrypt申請免費的SSL證書

    這篇文章主要為大家介紹了如何使用let's?encrypt申請免費的SSL證書示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 多種編程語言的常用按鍵和語法

    多種編程語言的常用按鍵和語法

    就我所知道的語言來說,在鍵盤上集中分布跨度更大的語音,通常就是我們所指的丑陋的語言(閱讀和編寫代碼都很困難),例如 shell 和 perl。
    2011-10-10
  • JetBrains公司三大編輯器迭代循環(huán)模板快捷鍵詳解

    JetBrains公司三大編輯器迭代循環(huán)模板快捷鍵詳解

    這篇文章主要介紹了JetBrains公司三大編輯器迭代循環(huán)模板快捷鍵,如果快捷鍵無用,請到keymap中調整自己的快捷鍵,或者查看是否有應用占用了該快捷鍵,需要的朋友可以參考下
    2022-04-04
  • 級聯分類器算法原理解析

    級聯分類器算法原理解析

    這篇文章主要為大家介紹了級聯分類器算法的原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • git merge最簡潔用法詳解

    git merge最簡潔用法詳解

    git-merge 命令是用于從指定的 commit(s) 合并到當前分支的操作,本文重點給大家介紹git merge最簡潔用法,感興趣的朋友跟隨小編一起看看吧
    2020-12-12
  • 基于語雀編輯器的在線文檔編輯與查看功能

    基于語雀編輯器的在線文檔編輯與查看功能

    語雀是一個非常優(yōu)秀的文檔和知識庫工具,其編輯器更是非常好用,雖無開源版本,但有編譯好的可以使用,本文基于語雀編輯器實現在線文檔的編輯與文章的預覽,感興趣的朋友一起看看吧
    2024-07-07
  • Chrome 調試技巧(小結)

    Chrome 調試技巧(小結)

    這篇文章主要介紹了Chrome 調試技巧(小結),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Git撤回已Push的代碼的方法大全

    Git撤回已Push的代碼的方法大全

    在日常的開發(fā)中,我們經常使用Git來進行版本控制,有時候,我們可能會不小心將錯誤的代碼 Push 到遠程倉庫,或者想要在本地回退到之前的某個版本重新開發(fā),所以本文給大家介紹了Git 如何撤回已 Push 的代碼,需要的朋友可以參考下
    2025-12-12

最新評論

隆尧县| 南和县| 中超| 元氏县| 石嘴山市| 旺苍县| 阿城市| 连南| 格尔木市| 偏关县| 乡城县| 博湖县| 建阳市| 泾源县| 阿克| 长岛县| 墨脱县| 策勒县| 宁晋县| 景谷| 古田县| 茂名市| 水城县| 定边县| 昂仁县| 英山县| 乌拉特前旗| 文安县| 阜平县| 育儿| 大埔区| 桦南县| 兴城市| 建宁县| 东宁县| 安图县| 介休市| 香格里拉县| 肇庆市| 大余县| 浮梁县|