git基础
Git 基础
Git 不仅是版本控制系统,还是内容寻址存储系统——它把每个文件的内容按 sha-1 值存放,分支、提交历史、工作流都建立在对象之上。
建议:命令行不熟时先用命令行学习原理,理解后再用可视化工具提高效率。推荐一款可视化工具(见下图):

特点
- 分布式:每个克隆出来的仓库都是一份完整版本库,离线也能提交、查历史。
- 内容寻址存储:内容按 sha-1 标识存储,相同内容只存一份。
- 无全局版本号:不像 SVN 有 1、2、3 递增版本号,提交用内容哈希(sha-1)标识。
基本概念
三个区域要分清,git 的所有命令本质都是在让文件在这三者之间移动:
| 区域 | 位置 | 作用 |
|---|---|---|
| 工作区(Working Tree) | 电脑里直接看到的目录 | 你编辑文件的地方 |
| 暂存区(Stage / Index) | 存放在版本库的 .git/index 文件里 |
准备提交的内容清单,git add 把改动放进来 |
| 版本库(Repository) | 工作区下的隐藏目录 .git |
保存提交历史和所有对象,不属于工作区 |
补充:远程仓库(Remote)——放在其他机器上的版本库,如 GitHub,用 pull/push 与它同步。

常规工作流:
工作区 → git add → 暂存区 → git commit → 版本库 → git push → 远程仓库
基本命令
1. 配置
git config --list # 查看当前配置
git config -e # 编辑当前仓库的配置
git config -e --global # 编辑全局配置(对所有仓库生效)
# 提交代码必需的用户信息
git config --global user.name 'user'
git config --global user.email 'name@163.com'
# 生成 SSH 密钥,并把公钥粘贴到 GitHub(实现免密推送)
ssh-keygen -t rsa -C "name@163.com"
cat ~/.ssh/id_rsa.pub
2. 日常提交流程
git init # 自建一个仓库
git clone [URL] # 克隆远程仓库到本地
git add <file> # 把工作区改动加入暂存区(git add . 表示全部)
git status # 查看工作区/暂存区状态,哪些文件待提交
git commit -m "说明" # 把暂存区内容提交到本地版本库
git commit sss.txt -m "说明" # 只提交这一个文件
git log # 查看提交历史
git diff # 工作区 vs 暂存区的差异
git diff --cached # 暂存区 vs 最后一次提交的差异
git tag v1.0 # 给当前提交打标签,如 v1.0、v1.2
3. 撤销与恢复
git reset HEAD <file> # 取消暂存:暂存区恢复成最后一次提交的状态,工作区不受影响
git rm --cached <file> # 停止跟踪该文件,但保留工作区文件(文件不再被 git 管理)
git checkout HEAD -- <file> # 丢弃工作区改动,把文件恢复到最后一次提交的内容
4. 分支管理
git branch # 查看分支
git checkout -b <name> # 创建新分支并切换过去
git checkout <name> # 切换分支(用该分支的内容更新暂存区和工作区)
git merge <name> # 把 <name> 分支合并到当前分支
git branch -d <name> # 删除已合并的本地分支
git branch -D <name> # 强制删除分支(即使没合并过)
5. 远程仓库
git remote 管理远程仓库的"通讯录"——记录别的机器上版本库的名字和地址。
origin 不是命令,而是远程仓库的默认名字(git clone 时自动命名)。
git remote -v # 查看远程仓库列表及 URL
git remote add origin <URL> # 添加远程仓库,命名为 origin
git remote set-url origin <URL> # 修改远程仓库地址
git remote remove <name> # 删除远程仓库
git pull origin branch-name # 从 origin 拉取分支并合并到当前分支
git push origin branch-name # 推送本地分支到 origin
git push origin --delete branch-name # 删除远程分支
6. 进阶:对象模型
提交不是保存"差异",而是生成一串对象,每个对象有唯一 sha-1 值:
git init mydemo1
git add "sss.txt"
git commit -m "sss.txt"
git tag v1.0
git log # 得到提交的 sha-1,如 828ac5d1670...
git cat-file commit 828ac5d... # 查看 commit 对象 → 得到它指向的 tree 对象
git ls-tree d80ee416... # 查看 tree 对象(目录结构)→ 得到 blob 对象
git cat-file blob 168a5454... # 查看 blob 对象 → 文件真实内容
关系链:commit(提交快照)→ tree(目录结构)→ blob(文件内容),用 sha-1 层层引用。
常见问题
为什么每个提交都有个 sha-1 值?
git 采用内容寻址:对象的 sha-1 由内容计算得到,内容一变、哈希就变。它既是对象的"门牌号",也能校验内容有没有被篡改。完整 sha-1 就是对象在 .git/objects 里的文件名。
裸库与非裸库
- 裸库(bare repo):只含
.git里的内容,没有工作区,不能直接编辑文件。用git init --bare创建。服务器端共享仓库(如 GitHub 上的仓库)通常是裸库。 - 非裸库:有工作区 +
.git。平时 clone 下来的本地仓库就是非裸库。
git 对象有哪几种?
4 种,全部存在 .git/objects,用 sha-1 互相引用:
- blob:文件的内容
- tree:目录结构(包含文件名、对 blob/subtree 的引用)
- commit:一次提交快照(指向 tree、父提交、作者、时间、说明)
- tag:给 commit 打的标签
git 钩子(Hooks)是什么?
.git/hooks/ 下的可执行脚本,在特定动作发生时自动触发,如 pre-commit(提交前)、commit-msg(检查提交信息)、post-receive(服务端收到推送后)。常用于自动检查代码规范、跑测试、自动部署。默认是 .sample 结尾的模板,去掉后缀并写入脚本即生效。
内网无法下载 git 库,怎么配代理?
git config --global http.proxy http://代理地址:端口
git config --global https.proxy http://代理地址:端口
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy

浙公网安备 33010602011771号