git分支是轻量级指针,非代码副本;git branch仅在.git/refs/heads/下创建指向某提交sha-1哈希的文本文件,该指针随提交自动前移,删分支只删文件,历史仍可通过reflog找回。

Git 分支不是“副本”,而是轻量级指针;分布式不是“多份拷贝”,而是每个本地仓库都自带完整历史图谱——这是所有操作不卡、不依赖网络、不怕丢数据的根本原因。
git branch 创建的到底是什么
git branch 命令不复制文件,也不生成新快照,它只是在 .git/refs/heads/ 下新建一个文本文件,内容是某个提交的 SHA-1 哈希值(比如 a1b2c3d4...)。这个文件就是分支指针。
- 分支名本质是“可移动的标签”,
git commit后,当前分支指针自动前移指向新提交 -
git checkout feature/login只是把HEAD指向那个分支文件,再把工作目录重置为该提交对应的状态 - 删除分支(
git branch -d)只是删掉那个文本文件,只要提交没被 GC,历史就还在
常见错误现象:以为删了分支就等于删了代码,结果发现 git reflog 还能找回;或者误以为切换分支会“同步远程”,其实只是本地指针跳转,和远程无关。
为什么 git clone 后能离线 commit、merge、rebase
因为git clone 下载的不只是最新代码,而是整个对象数据库(.git/objects/),包含:
- 所有提交对象(commit)
- 所有树对象(tree,即目录结构)
- 所有二进制 blob(file content)
- 所有引用(refs,包括远程分支如 origin/main)
这意味着:
-
git log查全部历史,不走网络 -
git merge feature/x是本地两个提交指针的 DAG 图谱运算,不需要服务器参与 -
git rebase main实际是把一串提交“重放”到另一个基底上,全程只读写本地对象库
性能影响:小仓库毫秒级完成,大仓库(如 Linux 内核)也只需几百毫秒——因为 Git 从不传输或解析完整文件,只按需解包压缩对象。
远程分支(如 origin/main)不是真实分支,而是本地记录
origin/main 是你本地仓库里一个叫 refs/remotes/origin/main 的文件,内容是上次 git fetch 时从远程拿到的 main 分支头提交哈希。
- 它不会自动更新:
git pull=git fetch+git merge,但fetch才真正同步远程状态 - 你不能直接
git checkout origin/main(会进入 detached HEAD),因为它只是个“快照标记”,不是可移动分支 -
git push origin feature/x的本质,是把你本地feature/x指针指向的提交,连同所有缺失的父提交,打包发给远程,并让远程的refs/heads/feature/x指向它
容易踩的坑:
- 把
origin/main当成远程实时状态,结果git status显示“Your branch is up to date”但远程其实已有新提交(因为没fetch) - 在 CI 脚本里用
git checkout origin/main导致后续git commit失败(detached HEAD 下不允许直接提交)
分支和远程的分离设计,让 Git 能在弱网、断网、甚至无远程仓库的情况下持续工作——真正的控制权始终在你本地。图谱存在那里,指针由你拨动,这才是分布式版本控制不可替代的底层事实。











