Git 是目前最主流的版本控制系统。本文从初始配置开始,覆盖日常开发中用到的绝大多数操作,包括分支、合并、变基、撤销、stash、协作流程等,尽量做到看完能直接上手。
初始配置
第一次使用 Git,先做全局配置:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
配置默认分支名(推荐 main):
git config --global init.defaultBranch main
配置默认编辑器(以 VS Code 为例):
git config --global core.editor "code --wait"
查看所有配置:
git config --list
创建仓库
从零开始:
mkdir my-project && cd my-project
git init
克隆已有仓库:
# HTTPS(需输入账号密码或 Token)
git clone https://github.com/user/repo.git
# SSH(需配置 SSH Key)
git clone git@github.com:user/repo.git
# 克隆到指定目录名
git clone git@github.com:user/repo.git my-folder
基础工作流
Git 的本地状态分三层:工作区 → 暂存区 → 本地仓库。
# 查看当前状态
git status
# 把文件加入暂存区
git add file.txt
git add . # 暂存所有改动
git add -p # 交互式选择要暂存的部分(很实用)
# 提交
git commit -m "feat: add user login"
# 跳过暂存,直接提交已追踪的修改
git commit -am "fix: correct typo"
提交信息规范(Conventional Commits)
好的提交信息便于阅读历史和自动生成 CHANGELOG:
type(scope): subject
feat 新功能
fix 修复 Bug
docs 文档变更
style 格式调整(不影响逻辑)
refactor 重构
test 添加或修改测试
chore 构建流程、工具配置等
查看历史
# 查看提交历史
git log
# 简洁一行格式
git log --oneline
# 带图形的分支视图
git log --oneline --graph --all
# 查看某个文件的历史
git log --follow -- path/to/file
# 查看某次提交的具体改动
git show <commit-hash>
分支管理
分支是 Git 最核心的能力,操作几乎无成本。
# 查看所有分支
git branch
git branch -a # 含远程分支
# 创建新分支
git branch feature/login
# 切换分支
git switch feature/login
# 创建并切换(常用简写)
git switch -c feature/login
# 删除分支
git branch -d feature/login # 安全删除(未合并时会提示)
git branch -D feature/login # 强制删除
# 重命名当前分支
git branch -m new-name
合并(Merge)
# 切到目标分支(通常是 main)
git switch main
# 合并 feature 分支
git merge feature/login
Fast-forward 合并:目标分支没有新提交,直接把指针前移,历史是一条直线。
非 Fast-forward 合并:目标分支有新提交,会产生一个合并提交(Merge Commit),历史保留分叉结构。
保留合并记录时加 --no-ff:
git merge --no-ff feature/login
解决冲突
合并冲突时,文件中会出现标记:
<<<<<<< HEAD
本地的内容
=======
合并进来的内容
>>>>>>> feature/login
手动编辑保留正确内容,然后:
git add .
git commit # Git 会自动填写合并提交信息
变基(Rebase)
Rebase 把当前分支的提交"接"到另一个分支的末尾,历史保持线性,更干净。
# 在 feature 分支上,把它接到 main 最新位置
git switch feature/login
git rebase main
交互式变基(整理提交历史非常有用):
# 修改最近 3 个提交
git rebase -i HEAD~3
在编辑器中可以选择:
| 命令 | 作用 |
|---|---|
pick | 保留该提交 |
reword | 保留但修改提交信息 |
squash | 合并到上一个提交 |
fixup | 同 squash,丢弃信息 |
drop | 删除该提交 |
注意: 不要对已推送到远程的公共分支做 rebase,会导致其他人的历史冲突。
远程仓库
# 查看远程仓库
git remote -v
# 添加远程
git remote add origin git@github.com:user/repo.git
# 修改远程 URL
git remote set-url origin git@github.com:user/new-repo.git
# 推送(第一次需要 -u 设置上游)
git push -u origin main
# 之后直接
git push
# 拉取(fetch + merge)
git pull
# 只拉取,不合并
git fetch origin
# 删除远程分支
git push origin --delete feature/login
暂存(Stash)
切换分支时有未提交的改动,不想提交又不想丢,用 stash:
# 暂存当前改动
git stash
# 附带说明
git stash push -m "wip: half-done login form"
# 查看 stash 列表
git stash list
# 恢复最近一次 stash(并保留在列表)
git stash apply
# 恢复并从列表删除
git stash pop
# 恢复指定的 stash
git stash apply stash@{2}
# 删除某个 stash
git stash drop stash@{0}
# 清空所有 stash
git stash clear
撤销操作
Git 的撤销命令比较多,分场景理解:
撤销工作区的修改(未 add)
# 恢复某个文件到最后一次提交的状态
git restore file.txt
# 恢复所有文件
git restore .
撤销暂存区(已 add,未 commit)
git restore --staged file.txt
修改最后一次提交
# 修改提交信息,或追加文件进去
git add forgotten-file.txt
git commit --amend
撤销某次提交(安全方式,生成一个反向提交)
git revert <commit-hash>
回退到某个历史版本(reset)
# 软回退:提交撤销,改动保留在暂存区
git reset --soft HEAD~1
# 混合回退(默认):提交撤销,改动回到工作区
git reset HEAD~1
# 硬回退:提交和改动都丢弃(危险,慎用)
git reset --hard HEAD~1
revertvsreset:
revert追加一次新提交来撤销,历史不变,适合公共分支reset直接修改历史,仅适合本地未推送的提交
标签(Tag)
通常用来标记版本发布:
# 创建轻量标签
git tag v1.0.0
# 创建附注标签(包含信息)
git tag -a v1.0.0 -m "Release version 1.0.0"
# 查看所有标签
git tag
# 推送标签到远程
git push origin v1.0.0
git push origin --tags # 推送所有标签
# 删除标签
git tag -d v1.0.0
git push origin --delete v1.0.0 # 删除远程标签
.gitignore
.gitignore 告诉 Git 哪些文件不需要追踪:
# 依赖目录
node_modules/
vendor/
# 构建输出
dist/
build/
*.min.js
# 环境变量
.env
.env.local
# 系统文件
.DS_Store
Thumbs.db
# IDE 配置
.vscode/
.idea/
已经被追踪的文件,加入 .gitignore 后不会自动忽略,需要先取消追踪:
git rm --cached file.txt # 取消追踪单个文件
git rm --cached -r node_modules/ # 取消追踪目录
协作场景
Fork + Pull Request 流程
- Fork 目标仓库到自己账号
- Clone 自己的 Fork
- 创建 feature 分支
- 开发、提交
- Push 到自己的 Fork
- 在 GitHub/GitLab 发起 Pull Request / Merge Request
保持 Fork 与上游同步:
# 添加上游远程
git remote add upstream git@github.com:original/repo.git
# 拉取上游最新
git fetch upstream
# 合并到本地 main
git switch main
git merge upstream/main
多人协作主要原则
main/master分支通常受保护,不允许直接 push- 每个功能开一个 feature 分支
- 合并前 rebase 到最新 main,减少冲突
- PR 里做 Code Review,再合并
常用快捷操作
# 查看两个分支的差异
git diff main feature/login
# 查看文件每一行是谁改的
git blame file.txt
# 用二分法找出引入 Bug 的提交
git bisect start
git bisect bad # 当前版本有问题
git bisect good v1.0.0 # 这个版本还好
# Git 自动帮你 checkout 中间版本,你测试后标记 good/bad
git bisect reset # 结束
# 挑选某个提交应用到当前分支
git cherry-pick <commit-hash>
# 清理未追踪的文件和目录
git clean -fd
常见问题
push 被拒绝(rejected)
通常因为远程有别人的新提交:
git pull --rebase # 拉取后变基,保持线性历史
git push
误删分支恢复
Git 的提交不会立即消失,可以通过 reflog 找回:
git reflog # 查看所有操作历史
git switch -c recovered-branch <commit-hash>
大文件误提交
大文件不应该进入 Git 仓库(会永久撑大仓库体积)。
如果已提交但未推送:
git rm --cached bigfile.zip
git commit --amend
如果已推送,需要用 git filter-repo(替代已废弃的 filter-branch)彻底清除历史,操作较复杂,建议提前用 .gitignore 规避。
Fonnpo