找回密码
 立即注册
首页 业界区 业界 开发者必看的 15 个困惑的 Git 术语(以及它们的真正含 ...

开发者必看的 15 个困惑的 Git 术语(以及它们的真正含义)

顾星 6 天前
PHP 开发者必看的 15 个困惑的 Git 术语(以及它们的真正含义)

做了多年开发, 自 2015 年开始使用 Git, 我审过数百个 Pull Request,收拾过无数混乱的代码仓库,也带过不少在 Git 命令里打转的新人。
老实说,我完全理解他们的困惑。Git 确实强大,但它的术语系统就像一个迷宫——很多词看着相似,实际用法却天差地别。
今天就来聊聊这些连老手都可能搞混的 Git 术语。如果你是新手,这篇文章能帮你少走很多弯路。
原文 开发者必看的 15 个困惑的 Git 术语(以及它们的真正含义)
HEAD vs head vs Detached HEAD

开发者常犯的错误:

把 HEAD 当成又一个分支名。
它的真实身份:

HEAD 是一个指针,指向你当前所在的 commit —— 通常是你所在分支的最新提交。
每次你提交代码,HEAD 就会移动到那个新 commit 上。
  1. # 查看 HEAD 指向哪里
  2. git log --oneline --decorate -n 3
  3. # --oneline 把每个 commit 压缩成一行显示:
  4. # commit hash 的前 7 个字符 + commit 信息
  5. # --decorate
  6. # 在 commit 旁边显示分支和标签引用
  7. # 这样你就能看到 HEAD、main、origin/main 或 v1.0.0 这些指针当前在哪
  8. # -n 3
  9. # 只显示最近 3 个 commit
复制代码
你会看到类似这样的输出:
  1. a3c4d5e (HEAD -> main, origin/main) Add user API
复制代码
如果你直接 checkout 到某个旧 commit:
  1. git checkout a3c4d5e
复制代码
你会看到这样的提示:You are in 'detached HEAD' state.
这只是说你现在不在任何分支上——你在查看历史快照。没什么坏事发生。
如果你想保存在这里做的工作:
  1. git switch -c hotfix/legacy-bug
复制代码
至于 head(小写),它不是 Git 的关键字——通常只是非正式用法或复数形式,比如"分支的 heads"。
Git 把分支的最新提交存在 .git/refs/heads/ 下,所以你可能会在内部引用中看到这个词。
比如:
  1. .git/refs/heads/main
  2. .git/refs/heads/feature/login
复制代码
所以当你看到"所有 heads"时,意思是"每个分支的最新 commit",而不是那个特殊的 HEAD 指针。
后缀的含义:

Git 提供了一些方式让你从 HEAD 开始往回追溯历史。
HEAD~1
表示"HEAD 之前的一个 commit"。
HEAD~2 表示"之前的两个 commit",以此类推。
  1. git show HEAD~1
复制代码
显示你当前 commit 的上一个。
HEAD^1 和 HEAD^2
这些是父指针。它们在处理 merge commit 时最有用。
一个 merge commit 有两个父节点——一个来自你所在的分支,另一个来自你合并进来的分支。
  1. git diff HEAD^1 HEAD^2
复制代码
对比合并时两边各自贡献了什么。
^1 表示"第一个父节点",^2 表示"第二个父节点"。
经验法则:


  • 用 ~ 线性地往回走
  • 用 ^ 处理 merge commit 的父节点
如下图演示

1.png

把 feature 合并到 main 后,merge commit (M) 有两个父节点:

  • HEAD^1 → commit C(合并前的 main)
  • HEAD^2 → commit E(feature 分支的末端)
一旦你把 HEAD 想象成"你在这里",Git 的导航模型就瞬间清晰了。
Commit vs Changeset

很多开发者以为 commit 就是 diff——其实不是。

  • commit = 仓库的完整快照 + 元数据 + 父节点链接
  • changeset = 两个 commit 之间的差异
  1. git show HEAD          # 显示 commit 及其 diff(changeset 视图)
  2. git diff HEAD~1 HEAD   # 只显示两个 commit 之间的原始 diff
  3. git add -p             # 选择性暂存变更(构建你的 changeset)
  4. git commit -m "Fix NPE in user lookup"
复制代码
理解这个区别能帮你打造原子化 commit——每个 commit 只包含一个逻辑变更——而不是一股脑全扔进去。
Branch ≠ Copy

创建分支不会克隆代码库。
它只是创建一个指向 commit 的新指针。
  1. git branch feature/login
  2. git switch feature/login
复制代码
现在你有了一个从 main 分叉出去的轻量级指针。没有额外文件,没有复制。
Tags

Tags 标记特定的 commit——通常用于发布版本,而且不会移动。
  1. git tag v1.0.0
  2. git push origin v1.0.0
复制代码
和分支不同,tags 是不可变的。一旦设置,它们永远指向同一个 commit。
Fast-Forward Merge

Fast-forward 不是什么特殊操作——它只是没有分叉的合并。
无分叉 -> 可以 Fast-forward

2.png

main 从 B 之后就没动过。
  1. git switch main
  2. git merge --ff-only feature
复制代码
结果:
3.png

没有创建 merge commit -> Git 只是把 main 的指针往前移了。
分支已分叉 -> 无法 Fast-forward

4.png

两边都在 B 之后有了新提交。
  1. git switch main
  2. git merge feature
复制代码
现在 Git 必须创建一个 merge commit 来合并 E 和 D。
如果你坚持要 fast-forward:
  1. git merge --ff-only feature
  2. # error: Not possible to fast-forward
复制代码
规则:

如果双方在分叉后都有新 commit,就无法 fast-forward。
Squash

Squash 在合并前把多个 commit 压扁成一个——适合清理混乱的 feature 分支历史。
  1. git merge --squash feature/login
  2. git commit -m "Add login feature"
复制代码
你的分支历史保持干净,同时在 PR 里不会丢失工作上下文。
origin vs upstream


这个挺有意思的……我几天前在处理一个 fork 项目时才搞清楚区别。之前我一直以为它俩是一回事
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

5 天前

举报

感谢,下载保存了
4 天前

举报

懂技术并乐意极积无私分享的人越来越少。珍惜
您需要登录后才可以回帖 登录 | 立即注册