一文带你搞懂 Git
从零开始,系统掌握 Git 版本控制的核心概念、常用命令与实战技巧。
一、Git 是什么
Git 是一个分布式版本控制系统(Distributed Version Control System),由 Linus Torvalds 在 2005 年创建。它的核心能力是:
- 追踪文件的每一次变更——谁在什么时间改了什么内容,全部有据可查
- 支持多人协作——多人同时开发同一项目,互不干扰
- 支持分支管理——可以在不同分支上独立开发,最后合并
- 离线可用——绝大多数操作在本地完成,不依赖网络
与 SVN 等集中式版本控制系统不同,Git 的每个克隆都是完整的仓库副本,拥有全部历史记录。
二、安装 Git
2.1 下载
- 官方网站:git-scm.com(速度较慢)
- 推荐使用 清华大学开源软件镜像站 下载
2.2 安装后验证
bash
git --version
出现版本号即安装成功。
三、核心概念:三大区域
理解 Git 的关键在于理解它的三个工作区域:
┌──────────────┐ git add ┌──────────────┐ git commit ┌──────────────┐
│ │ ───────────► │ │ ─────────────► │ │
│ 工作区 │ │ 暂存区 │ │ 版本库 │
│ Working Dir │ ◄─────────── │ Staging Area│ ◄──────────── │ Repository │
│ │ git restore │ │ git reset │ │
└──────────────┘ └──────────────┘ └──────────────┘
| 区域 | 说明 |
|---|---|
| 工作区(Working Directory) | 你在电脑上能看到的目录,就是你正在编辑的文件 |
| 暂存区(Staging Area / Index) | 临时存放即将提交的改动,相当于"购物车" |
| 版本库(Repository) | Git 正式记录历史的地方,每次 commit 生成一个快照 |
一次完整的提交流程:
修改文件 → git add(放入暂存区)→ git commit(写入版本库)→ git push(推送到远程)
四、初始配置
安装完成后,第一件事是配置你的身份信息,因为每次提交都会记录这些信息。
4.1 全局配置(对所有仓库生效)
bash
git config --global user.name '你的名字'
git config --global user.email '你的邮箱@example.com'
或者直接编辑配置文件:
bash
vim ~/.gitconfig
4.2 本地仓库配置(仅对当前仓库生效)
bash
git config user.name '你的名字'
git config user.email '你的邮箱@example.com'
4.3 查看所有配置
bash
git config --list
五、仓库的创建与克隆
5.1 克隆远程仓库
bash
# 克隆完整仓库
git clone https://github.com/user/project.git
# 克隆指定分支
git clone -b branch_name https://github.com/user/project.git
Git 支持多种协议:ssh://、http(s)://、git://,或者直接用用户名(Git 会默认使用 SSH 协议)。
5.2 初始化本地仓库
bash
mkdir my-project && cd my-project
git init
这会在当前目录下创建一个 .git 隐藏文件夹,这就是 Git 仓库的核心。
5.3 关联远程仓库
bash
# 添加远程仓库
git remote add origin https://github.com/user/project.git
# 查看远程仓库
git remote -v
六、日常操作:增改提交
6.1 查看状态
bash
git status # 查看工作区状态
git diff # 查看未暂存的改动
git diff --staged # 查看已暂存但未提交的改动
6.2 添加到暂存区
bash
git add file.txt # 添加指定文件
git add . # 添加所有改动(当前目录及子目录)
git add -A # 添加所有改动(整个仓库)
6.3 提交到版本库
bash
git commit -m "feat: 添加用户登录功能"
git commit --amend # 修改最近一次提交(合并到上一次提交,不产生新记录)
6.4 推送到远程
bash
git push origin main # 推送到远程 main 分支
git push -u origin feature # 首次推送并建立关联,后续直接 git push
⚠️ 尽量不要使用
git push -f强制推送,这会覆盖远程历史,可能导致他人代码丢失。
七、分支管理
分支是 Git 最强大的特性之一。它让你可以在不影响主线的情况下独立开发新功能。
7.1 查看分支
bash
git branch # 查看本地分支(* 号标识当前分支)
git branch -r # 查看远程分支
git branch -a # 查看本地 + 远程分支
7.2 创建与切换分支
bash
git branch experimental # 创建分支但不切换
git checkout develop # 切换到 develop 分支
git checkout -b localdev # 创建并切换到新分支(等价于上面两步)
新版 Git 推荐使用
git switch和git restore替代git checkout的部分功能:
bashgit switch develop # 切换分支 git switch -c localdev # 创建并切换分支
7.3 合并分支
bash
git merge feature # 将 feature 分支合并到当前分支
合并时可能产生冲突,需要手动编辑冲突文件,解决后重新 git add 和 git commit。
7.4 删除分支
bash
git branch -d localdev # 删除本地分支(安全删除,未合并会提示)
git branch -D localdev # 强制删除本地分支
git push origin -d feature # 删除远程分支
7.5 将本地分支与远程分支关联
bash
git branch --set-upstream-to=origin/feature feature
# 格式:git branch --set-upstream-to=远程分支名 本地分支名
八、拉取与获取
8.1 git pull(拉取并合并)
bash
# 将远程指定分支拉取到本地指定分支
git pull origin <远程分支名>:<本地分支名>
# 将远程指定分支拉取到当前分支
git pull origin <远程分支名>
# 拉取与当前分支关联的远程分支
git pull
8.2 git fetch(仅获取,不合并)
bash
git fetch --all # 获取所有远程更新,但不改动本地代码
git pull=git fetch+git merge。如果你只想看看远程有什么变化但不想自动合并,用git fetch。
九、撤销操作
这是日常开发中最容易搞混的部分,以下是清晰对照:
| 场景 | 命令 | 说明 |
|---|---|---|
| 撤销工作区的修改 | git checkout -- file 或 git restore file |
恢复到最近一次 commit/add 的状态 |
取消 git add |
git reset file 或 git restore --staged file |
从暂存区移除,保留工作区改动 |
| 取消最近的 commit(保留改动) | git reset --soft HEAD^ |
撤销 commit,不撤销 add,代码改动保留 |
| 取消最近的 commit(连 add 一起撤销) | git reset --mixed HEAD^ |
撤销 commit 和 add,代码改动保留(默认模式) |
| 彻底放弃所有本地改动 | git reset --hard HEAD^ |
⚠️ 危险!撤销 commit + add + 工作区改动 |
| 撤销已 push 的提交 | git revert <commit-hash> |
生成一个反向提交,安全且不改写历史 |
bash
# 取消 rebase
git rebase --abort
# 解决 "you need to resolve your current index first" 错误
git reset --merge
十、Git Stash:临时保存
当你正在开发某个功能,突然需要切换分支修 Bug,但当前代码还没写完不想提交——git stash 就是为你准备的。
bash
git stash # 保存当前未 commit 的代码
git stash save "修复登录bug一半" # 保存并添加备注
git stash list # 查看所有暂存记录
git stash pop # 恢复最近的暂存,并删除该记录
git stash pop stash@{0} # 恢复指定的暂存记录
git stash apply # 恢复最近的暂存,但保留记录
git stash drop # 删除最近的一次 stash
git stash clear # 清空所有 stash 记录
十一、标签管理(Tag)
标签常用于标记版本发布点,如 v1.0.0。
bash
git tag # 列出所有标签
git show v1.4 # 查看指定标签信息
git tag -a v1.4 -m "my version 1.4" # 创建附注标签
git push origin v1.4 # 推送指定标签到远程
git push origin --tags # 推送所有标签到远程
git tag -d v1.4 # 删除本地标签
十二、.gitignore 文件
.gitignore 用于指定哪些文件/目录不被 Git 追踪。常见需要忽略的内容:
- 编译产物(
build/、dist/、*.class) - 依赖目录(
node_modules/、venv/) - IDE 配置(
.idea/、.vscode/) - 系统文件(
.DS_Store、Thumbs.db) - 敏感信息(
.env、密钥文件)
示例(Python 项目):
gitignore
__pycache__/
*.py[cod]
*.so
.env
.venv
venv/
.vscode/
*.egg-info/
dist/
build/
误上传了不该传的文件怎么办?(例如
node_modules)
bashgit rm -r --cached node_modules # 从 Git 追踪中移除(本地文件保留) git commit -m "remove node_modules from tracking"如果需要彻底清除历史记录中的大文件,可以使用 BFG Repo-Cleaner 工具。
十三、提交规范
良好的提交信息让项目历史清晰可读。推荐使用 Conventional Commits 规范:
<type>(<scope>): <subject>
<body>
<footer>
常用 type:
| type | 说明 |
|---|---|
feat |
新功能 |
fix |
修复 Bug |
docs |
文档变更 |
style |
代码格式调整(不影响功能) |
refactor |
重构(既不是新功能也不是修 Bug) |
test |
增加或修改测试 |
chore |
构建工具、依赖等杂项变更 |
示例:
bash
git commit -m "feat(auth): 添加 OAuth2 登录支持"
git commit -m "fix(api): 修复用户列表分页越界问题"
git commit -m "docs: 更新 README 安装说明"
配置提交模板
bash
# 1. 创建模板文件
vim ~/.gitcommit
# 2. 模板内容
# [Required] 50-character subject line
# Code Source From: [Required]
# # Self Code / OpenSource / 3rd party Code / Other
# Description: [Optional]
# 3. 使配置生效
git config --global commit.template ~/.gitcommit
十四、实战场景速查
场景 1:强制覆盖本地代码(放弃所有本地修改)
bash
git fetch --all
git reset --hard origin/master
或单条命令:
bash
git fetch --all && git reset --hard origin/master && git pull
git fetch --all:拉取所有远程更新,不同步到本地git reset --hard origin/master:本地代码强制同步到远程最新版本git pull:再次更新(可省略,上一步已完成)
场景 2:清空所有提交记录
bash
git checkout --orphan latest_branch # 检出全新分支(无历史)
git add . # 添加所有文件
git commit -m "初始化仓库" # 提交
git branch -D master # 删除原 master 分支
git branch -m latest_branch master # 将新分支重命名为 master
git push -f origin master # 强制推送到远程
git branch --set-upstream-to=origin/master master # 关联远程分支
场景 3:撤销已推送的提交
bash
git revert 61db6174 # 生成一个反向提交来撤销指定 commit
git push # 推送撤销操作
git revert不会改写历史,而是新增一个"反向"提交,适合已 push 的场景。
场景 4:修改最近一次提交的信息
bash
git commit --amend -m "新的提交信息"
# 如果已经 push 过,需要强制推送(谨慎!)
git push -f
十五、命令速查表
========== 配置 ==========
git config --global user.name 'name' # 设置全局用户名
git config --global user.email 'email' # 设置全局邮箱
git config --list # 查看所有配置
========== 仓库 ==========
git init # 初始化本地仓库
git clone <url> # 克隆远程仓库
git clone -b <branch> <url> # 克隆指定分支
git remote add origin <url> # 添加远程仓库
git remote -v # 查看远程仓库
========== 基本操作 ==========
git status # 查看状态
git add . # 添加所有改动到暂存区
git commit -m "msg" # 提交
git push origin <branch> # 推送
git pull # 拉取并合并
git fetch --all # 拉取但不合并
========== 分支 ==========
git branch # 查看本地分支
git branch -a # 查看所有分支
git checkout -b <name> # 创建并切换分支
git merge <branch> # 合并分支
git branch -d <name> # 删除分支
git branch -D <name> # 强制删除分支
========== 撤销 ==========
git restore <file> # 撤销工作区修改
git reset <file> # 取消暂存
git reset --soft HEAD^ # 撤销 commit(保留改动)
git reset --hard HEAD^ # 撤销 commit(丢弃改动)
git revert <commit> # 撤销已推送的提交
========== 暂存 ==========
git stash # 临时保存
git stash list # 查看暂存列表
git stash pop # 恢复并删除记录
git stash apply # 恢复但保留记录
========== 标签 ==========
git tag # 查看标签
git tag -a v1.0 -m "msg" # 创建标签
git push origin --tags # 推送所有标签
git tag -d v1.0 # 删除标签
========== 其他 ==========
git log --oneline --graph # 查看提交历史(图形化)
git blame <file> # 查看文件每行最后修改者
git reflog # 查看所有操作记录(救命命令)
十六、常见问题
Q: git pull 和 git fetch 有什么区别?
git fetch只下载远程更新到本地,不改动工作区。git pull=git fetch+git merge,会直接合并到当前分支。
Q: git merge 和 git rebase 有什么区别?
merge会生成一个新的合并提交,保留完整的分支历史。rebase会将当前分支的提交"嫁接"到目标分支顶端,历史更线性整洁,但会改写提交记录。已推送的分支不要 rebase。
Q: 代码回退后怎么找回来?
使用
git reflog查看所有操作记录,找到之前的 commit hash,然后git reset --hard <hash>即可恢复。
Q: git reset 的 --soft、--mixed、--hard 区别?
--soft:只移动 HEAD 指针,暂存区和工作区不变--mixed(默认):移动 HEAD,重置暂存区,工作区不变--hard:移动 HEAD,重置暂存区和工作区(⚠️ 不可恢复,除非用 reflog)
总结:Git 的学习曲线确实存在,但核心就三件事——暂存(add)、提交(commit)、同步(push/pull)。掌握这三个动作加上分支管理,就能应对 90% 的日常场景。遇到问题不要慌,
git status看状态,git reflog找历史,一切皆可挽回。
Share