中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

開發者必看的(de) 15 個困惑的(de) Git 術語(以及它們的(de)真正含義)

PHP 開發者必看的 15 個困惑的 Git 術語(以及它們的真正含義)

做了多年開發, 自 2015 年開始使用 Git, 我審過(guo)數(shu)百個 Pull Request,收拾(shi)過(guo)無數(shu)混亂的(de)代碼倉庫,也帶過(guo)不少在 Git 命令里打轉的(de)新人。

老實說,我完全理解他們的困惑。Git 確實強大,但它的術語系統就像一個迷宮——很多詞看著相似,實際(ji)用(yong)法(fa)卻天差地別。

今(jin)天就來聊聊這些連老手(shou)都可(ke)能搞混的 Git 術語(yu)。如果你(ni)是新手(shou),這篇(pian)文章能幫(bang)你(ni)少走很多彎路。

HEAD vs head vs Detached HEAD

開發者常犯的錯誤:

把 HEAD 當成又一(yi)個(ge)分(fen)支(zhi)名(ming)。

它的真實身份:

HEAD 是一個指針,指向你當前所在的 commit —— 通常是你(ni)所(suo)在(zai)分支的最新提交。

每(mei)次你(ni)提交代碼(ma),HEAD 就會移動到那個新 commit 上。

# 查看 HEAD 指向哪里
git log --oneline --decorate -n 3

# --oneline 把每個 commit 壓縮成一行顯示:
# commit hash 的前 7 個字符 + commit 信息

# --decorate
# 在 commit 旁邊顯示分支和標簽引用
# 這樣你就能看到 HEAD、main、origin/main 或 v1.0.0 這些指針當前在哪

# -n 3
# 只顯示最近 3 個 commit

你會看到類似(si)這樣的輸出:

a3c4d5e (HEAD -> main, origin/main) Add user API

如果你直(zhi)接(jie) checkout 到(dao)某個(ge)舊 commit:

git checkout a3c4d5e

你會看到這樣的提示:You are in 'detached HEAD' state.

這(zhe)只(zhi)是說你現在(zai)不在(zai)任(ren)何分支上(shang)——你在(zai)查看(kan)歷史快照(zhao)。沒什(shen)么壞事發生。

如果你想保存在這里做的工(gong)作:

git switch -c hotfix/legacy-bug

至于 head(小寫),它不是 Git 的關鍵字——通常只是非正(zheng)式(shi)用(yong)法或復數形(xing)式(shi),比如"分支的 heads"。

Git 把分支的最新提交存在 .git/refs/heads/ 下,所以你可能會在(zai)內部引用中看(kan)到這個詞(ci)。

比如:

.git/refs/heads/main
.git/refs/heads/feature/login

所以當你看(kan)到"所有 heads"時,意思是"每個分支(zhi)的最新 commit",而不是那(nei)個特(te)殊的 HEAD 指針。

后綴的含義:

Git 提(ti)供(gong)了一些方式讓你從 HEAD 開始往回(hui)追溯歷史(shi)。

HEAD~1

表示(shi)"HEAD 之前的一個 commit"。

HEAD~2 表(biao)示"之前的兩個 commit",以此類推。

git show HEAD~1

顯示(shi)你(ni)當前 commit 的上一個。

HEAD^1 和 HEAD^2

這些是(shi)父(fu)指針。它們在處理 merge commit 時(shi)最(zui)有用。

一個(ge)(ge) merge commit 有兩個(ge)(ge)父節(jie)點——一個(ge)(ge)來自(zi)你所在的分支,另一個(ge)(ge)來自(zi)你合(he)并(bing)進來的分支。

git diff HEAD^1 HEAD^2

對比合(he)并時(shi)兩邊各(ge)自(zi)貢獻了什么。

^1 表示"第(di)一個父(fu)節(jie)點",^2 表示"第(di)二個父(fu)節(jie)點"。

經驗法則:

  • ~ 線性地往回走
  • ^ 處理 merge commit 的父節點

如下圖演示

15 個讓開發者困惑的 Git 術語(以及它們的真正含義)-CatchAdmin PHP 后臺管理框架

把(ba) feature 合并到 main 后,merge commit (M) 有兩個父節點(dian):

  • HEAD^1 → commit C(合并前的 main)
  • HEAD^2 → commit E(feature 分支的末端)

一旦你(ni)把 HEAD 想象成"你(ni)在這(zhe)里",Git 的導航模(mo)型就瞬間清晰(xi)了。

Commit vs Changeset

很(hen)多開發(fa)者(zhe)以(yi)為 commit 就(jiu)是 diff——其(qi)實不是。

  • commit = 倉庫的完整快照 + 元數據 + 父節點鏈接
  • changeset = 兩個 commit 之間的差異
git show HEAD          # 顯示 commit 及其 diff(changeset 視圖)
git diff HEAD~1 HEAD   # 只顯示兩個 commit 之間的原始 diff
git add -p             # 選擇性暫存變更(構建你的 changeset)
git commit -m "Fix NPE in user lookup"

理解這個區別能幫你打造原子化 commit——每(mei)個 commit 只包含(han)一個邏(luo)輯(ji)變(bian)更——而不(bu)是一股腦全扔(reng)進去。

Branch ≠ Copy

創建分支(zhi)不會克隆代(dai)碼(ma)庫。

它只是創(chuang)建一個指向 commit 的新指針。

git branch feature/login
git switch feature/login

現在你(ni)有了一個從 main 分叉出去的輕(qing)量級指針。沒有額外文件,沒有復(fu)制。

Tags

Tags 標記(ji)特定(ding)的(de) commit——通常用(yong)于發布(bu)版本,而(er)且不(bu)會移動。

git tag v1.0.0
git push origin v1.0.0

和(he)分支不(bu)同,tags 是不(bu)可變的。一旦設置,它們永遠指(zhi)向同一個 commit。

Fast-Forward Merge

Fast-forward 不是什么(me)特殊操作——它(ta)只(zhi)是沒有分叉的合并。

無分叉 -> 可以 Fast-forward

15 個讓開發者困惑的 Git 術語(以及它們的真正含義)-CatchAdmin PHP 后臺管理框架

mainB 之后就沒動過。

git switch main
git merge --ff-only feature

結果:


沒有創建 merge commit -> Git 只是把 main 的(de)指針往前(qian)移了。

分支已分叉 -> 無法 Fast-forward

15 個讓開發者困惑的 Git 術語(以及它們的真正含義)-CatchAdmin PHP 后臺管理框架

兩邊都在 B 之后有了新提交。

git switch main
git merge feature

現在 Git 必須創建一個 merge commit 來合并 ED

如果(guo)你(ni)堅持要(yao) fast-forward:

git merge --ff-only feature
# error: Not possible to fast-forward

規則:

如果雙(shuang)方在分(fen)叉后都有新 commit,就(jiu)無(wu)法(fa) fast-forward。

Squash

Squash 在合(he)并前把多(duo)個 commit 壓扁成一(yi)個——適合(he)清(qing)理(li)混(hun)亂的(de) feature 分支歷史。

git merge --squash feature/login
git commit -m "Add login feature"

你的(de)分支歷(li)史保持干凈(jing),同(tong)時在 PR 里不會丟失工作上下文。

origin vs upstream

這個挺有意思的……我(wo)幾(ji)天前在(zai)處理一個 fork 項目時才(cai)搞(gao)清楚(chu)區別。之前我(wo)一直以為它倆是一回事 ??

origin 是你克隆倉庫時默認的遠(yuan)程倉庫名稱。

如果你 fork 了一個倉庫,原始倉庫叫做 upstream

git remote -v

你可能會看到:

origin   git@github.com:yourname/project.git
upstream git@github.com:org/project.git

用 upstream 從原始源拉(la)取變(bian)更:

git fetch upstream

Remote-Tracking Branches

origin/mainmain 不是一回事。

  • main = 你的本地分支
  • origin/main = Git 對遠程 main 的最后已知快照
git fetch
git diff main origin/main

這(zhe)能(neng)告訴你上(shang)游有什么變化,而不(bu)用(yong)立即合并。

Fetch vs Pull

git fetch 只更新(xin)你對遠(yuan)程倉庫(ku)的本地(di)認知(zhi)。

git pull 做了這個,然后自(zi)動(dong)合并(或(huo) rebase)。

git fetch origin
git merge origin/main

這比盲目 git pull 更安全、更明確。

The Staging Area (Index)

暫(zan)存區是 Git 的"候車室(shi)"。

你決(jue)定哪些變更進入下(xia)一個 commit。

git add src/App.java
git status
git commit -m "Fix null check"

你可以暫存特定的代(dai)碼(ma)塊:

git add -p

就像在(zai)結賬(zhang)前往購物車里放東西。

Working Directory

你(ni)的(de)工作(zuo)目錄就是你(ni)正在編(bian)輯(ji)的(de)文件——不是倉庫(ku)本身。

真正的倉庫在 .git/ 里。

git status
# "working tree clean" 意思是你的文件和 HEAD 一致

Tracked vs Untracked Files

你添加過一次的文(wen)件是"已跟蹤(zong)"的。

新文(wen)件在你暫存它們之前不會被跟蹤。

git status
# Untracked files: (use "git add <file>")

提交(jiao)前一定要檢查這(zhe)個——未(wei)跟蹤的文(wen)件不會出現(xian)在 commit 里。

Dirty Tree

"Dirty tree" 只是(shi)說你的工(gong)作目錄(lu)有(you)未提交的變(bian)更。

git status
# modified: src/App.java

切換分支(zhi)前(qian)先提交或 stash 它們,避免沖(chong)突。

Reset vs Revert

Git 里(li)最容易被誤解的兩個(ge)命令。

  • reset 移動 HEAD,可能會丟棄 commit(危險)
  • revert 創建一個新 commit 來撤銷之前的變更(安全)
git reset --hard HEAD~1   # 刪除最后一個 commit
git revert HEAD           # 通過添加新 commit 安全地撤銷

如果你在共享分支上工作,永遠用 revert

總結

從本質上講,Git 就是一個由 commit指針 組成的圖。

一旦你理解了 HEAD分支快照 的(de)工作原理(li),其(qi)他一切都會(hui)變得合乎邏輯(ji)。

posted @ 2025-10-29 07:25  JaguarJack  閱讀(454)  評論(4)    收藏  舉報