Git 工作流笔记:日常开发与常用操作
这篇笔记从日常开发出发,整理 Git 的基本协作流程,以及查看改动、分支管理、撤销与恢复、同步远程、解决冲突等常用操作。示例默认远程仓库名为 origin,主分支名为 main;如果仓库使用 master 或其他名称,请替换示例中的分支名。
操作前先看状态。 执行切分支、重置、清理或变基等操作前,先运行
git status,确认当前分支和未提交改动,避免误覆盖工作。
目录
- 克隆仓库与基础配置
- 日常开发闭环
- 查看改动与提交历史
- 暂存、提交与提交信息
- 分支管理
- 同步远程与选择合并方式
- 冲突处理
- 撤销与恢复
- 暂存未完成的工作
- 远程仓库与清理分支
- Pull Request 与合并
- 标签与版本发布
- 常见问题速查
1. 克隆仓库与基础配置
使用 SSH 或 HTTPS 克隆仓库:
1
2
3
4
5
6
7
git clone git@github.com:username/repo.git
cd repo
# 查看远程地址、当前分支和工作区状态
git remote -v
git branch --show-current
git status
配置提交身份。全局配置对这台机器上的所有仓库生效;也可以进入具体仓库后去掉 --global,只为当前仓库设置:
1
2
3
4
5
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# 查看配置
git config --global --list
2. 日常开发闭环
通常为每项任务单独创建功能分支,在分支上提交,再通过 PR 合并回主分支:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 获取远程分支信息,并更新本地 main
git fetch origin
git switch main
git pull --ff-only origin main
# 创建并切换到功能分支
git switch -c feature/add-login
# 修改文件后检查状态和差异
git status
git diff
# 暂存、复查并提交
git add src/
git diff --staged
git commit -m "feat: add login"
# 首次推送时设置上游分支
git push -u origin feature/add-login
完成后,在 GitHub 上创建 PR。PR 合并后更新本地 main,再清理已经完成的功能分支:
1
2
3
git switch main
git pull --ff-only origin main
git branch -d feature/add-login
建议分支名包含用途和简短描述,例如:
| 前缀 | 用途 | 示例 |
|---|---|---|
feature/ | 新功能 | feature/add-login |
fix/ | 缺陷修复 | fix/login-timeout |
docs/ | 文档修改 | docs/git-workflow |
refactor/ | 重构 | refactor/user-service |
chore/ | 构建、依赖或配置 | chore/update-dependencies |
3. 查看改动与提交历史
提交前检查工作区和暂存区,确认只包含本次任务的内容:
1
2
3
4
5
6
7
git status # 完整状态
git status --short # 精简状态
git diff # 工作区中尚未暂存的改动
git diff --staged # 已暂存、下一次提交将包含的改动
git diff --check # 检查空白字符错误
git diff --stat # 改动文件和行数统计
git diff -- src/app.js # 只看指定文件
查看提交记录和分支图:
1
2
3
4
git log --oneline # 当前分支提交记录
git log --oneline --graph --decorate --all
git show <commit> # 查看某次提交的内容
git diff main...HEAD # 当前分支相对 main 分叉点之后的改动
4. 暂存、提交与提交信息
优先按文件或目录暂存,避免把无关改动一起提交:
1
2
3
4
5
git add src/app.js # 暂存指定文件
git add src/ # 暂存指定目录
git add -p # 交互式选择部分代码块
git add -A # 暂存新增、修改和删除
git restore --staged README.md # 从暂存区撤回,保留工作区改动
确认 git diff --staged 后再提交:
1
2
git commit -m "feat: add login"
git commit # 打开编辑器填写提交说明
提交信息可以采用 Conventional Commits 格式:
1
<type>(可选范围): 简短说明
| 类型 | 含义 |
|---|---|
feat | 新功能 |
fix | 修复问题 |
docs | 文档 |
style | 不影响逻辑的格式调整 |
refactor | 重构 |
test | 测试 |
perf | 性能优化 |
chore | 构建、依赖或其他维护工作 |
修改最近一次提交的信息或补入遗漏文件:
1
2
git add forgotten-file.txt
git commit --amend
--amend 会替换最近一次提交。如果该提交已经推送,修改后需要改写远程历史;除非确定自己是唯一协作者且团队允许,否则不要这样做。
5. 分支管理
1
2
3
4
5
git switch main # 切换分支
git switch -c feature/new-task # 创建并切换到新分支
git branch # 查看本地分支
git branch -a # 查看本地和远程跟踪分支
git branch -vv # 查看分支及其上游关系
删除已合并的本地分支:
1
git branch -d feature/old-task
-d 会在分支尚未合并时拒绝删除。-D 会强制删除,可能丢失该分支上尚未合并的提交;只有确认不再需要时才使用。
6. 同步远程与选择合并方式
fetch 只更新本地记录的远程分支,不会改动当前分支文件;pull 则会获取更新并将其整合到当前分支。
1
2
3
git fetch origin
git status -sb
git log --oneline --decorate --all -10
将远程主分支更新到本地 main。--ff-only 只允许快进更新;如果本地和远程已经分叉,它会停止而不是自动创建合并提交:
1
2
git switch main
git pull --ff-only origin main
功能分支开发期间,需要纳入 main 的新提交时,有两种常见方式:
Merge:保留分支汇合记录,不改写已有提交。
1
2
3
git fetch origin
git switch feature/add-login
git merge origin/main
Rebase:把自己的提交移到最新 main 之后,历史更线性。
1
2
3
git fetch origin
git switch feature/add-login
git rebase origin/main
rebase 会重写被移动提交的 SHA。只对自己独占的功能分支使用;已共享给他人的分支优先使用 merge,不要擅自改写公共历史。若变基后的分支已经推送,确认远程没有他人新提交后再使用:
1
git push --force-with-lease origin feature/add-login
不要用不带保护的 git push --force 覆盖远程分支。
7. 冲突处理
合并或变基遇到冲突时,先查看状态并打开冲突文件。文件中的 <<<<<<<、=======、>>>>>>> 标记出双方内容;编辑文件、保留正确结果并删除这些标记后,检查改动:
1
2
git status
git diff
确认解决结果后,分别继续对应操作:
1
2
3
4
5
6
7
# merge 冲突解决后
git add <已解决的文件>
git commit
# rebase 冲突解决后
git add <已解决的文件>
git rebase --continue
如果要放弃当前操作并回到开始前的状态:
1
2
git merge --abort
git rebase --abort
不要用 git add . 代替检查;逐个暂存已确认解决的文件更稳妥。
8. 撤销与恢复
撤销前先区分:改动还在工作区、已经暂存、已经提交,还是已经推送。不同状态使用不同命令。
未暂存的改动:
1
git restore src/app.js
这会丢弃该文件未暂存的修改,通常无法通过 Git 找回。执行前确认无需保留。
已暂存但尚未提交:
1
git restore --staged src/app.js # 取消暂存,改动仍保留在工作区
最近一次提交尚未推送:
1
2
git reset --soft HEAD~1 # 撤销提交,改动保留在暂存区
git reset HEAD~1 # 撤销提交,改动保留在工作区
提交已经推送或被他人使用:
1
git revert <commit>
revert 会创建一个新的反向提交,不改写已有公共历史,通常是撤销已共享提交的安全方式。
误删分支或找回不小心移动的提交:
1
git reflog
找到目标提交的哈希后,可以先创建恢复分支保留它:
1
git switch -c recovery/restore-work <commit>
reflog 记录本机近期的 HEAD 变动,不是远程备份;清理过期记录或长期未访问后,记录可能不可用。
9. 暂存未完成的工作
需要临时切换任务,但又不想提交当前改动时,可以使用 stash:
1
2
3
4
git stash push -m "login flow in progress"
git stash push -u -m "include new files" # 同时保存未跟踪文件
git stash list
git stash show -p stash@{0}
恢复改动:
1
2
git stash apply stash@{0} # 恢复但保留 stash 记录
git stash pop # 恢复并移除最近一条记录
确认不再需要某条记录后再删除:
1
git stash drop stash@{0}
stash pop 发生冲突时,冲突需要像普通改动一样解决;stash 记录可能会保留。重要工作不要只放在 stash 中,确认恢复到工作区或另行提交后再清理。
10. 远程仓库与清理分支
1
2
3
4
5
git remote -v # 查看远程地址
git remote add upstream <repository-url> # 添加上游仓库
git fetch upstream # 获取上游更新
git push -u origin feature/add-login # 首次推送并设置上游
git push # 后续推送
远程分支已在 GitHub 上删除时,清理本地过期的远程跟踪记录:
1
git fetch --prune
需要从 Git 取消跟踪某文件、但保留本地文件时:
1
git rm --cached .env
之后将文件加入 .gitignore 并提交变更。.gitignore 只影响尚未被 Git 跟踪的文件;若密钥已经提交,还需要立即轮换密钥,单纯删除文件并不能让旧密钥失效。
11. Pull Request 与合并
推送功能分支后,在 GitHub 创建 PR,描述改动目的、主要内容、验证方式和需要关注的风险。也可以使用 GitHub CLI:
1
gh pr create --base main --head feature/add-login
审查和 CI 通过后,根据仓库约定选择合并策略:
| 策略 | 结果 | 常见用途 |
|---|---|---|
| Merge commit | 保留分支提交,并生成合并提交 | 希望保留分支合并节点 |
| Squash and merge | 将 PR 提交压缩为一个提交 | 功能分支中有较多过程性提交 |
| Rebase and merge | 将提交线性应用到目标分支 | 分支中的提交已经清晰、独立 |
PR 合并后:
1
2
3
4
git switch main
git pull --ff-only origin main
git branch -d feature/add-login
git fetch --prune
如果远程功能分支没有自动删除,也可以在确认 PR 已合并后删除:
1
git push origin --delete feature/add-login
12. 标签与版本发布
标签常用于标记发布版本。带说明的附注标签通常更适合作为正式版本标记:
1
2
3
4
5
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin v1.2.0
git push origin --tags # 推送所有本地标签
git tag # 查看标签
git show v1.2.0 # 查看标签指向的提交和说明
删除本地标签和远程标签:
1
2
git tag -d v1.2.0
git push origin --delete v1.2.0
删除前确认版本发布流程允许;已公开使用的版本标签不应随意移动或重建。
13. 常见问题速查
| 场景 | 操作 |
|---|---|
| 忘记当前在哪个分支 | git branch --show-current |
| 不确定哪些内容会被提交 | git status、git diff --staged |
| 误把文件加入暂存区 | git restore --staged <file> |
| 想临时保存未完成改动 | git stash push -u -m "描述" |
| 只想获取远端信息、不整合到当前分支 | git fetch origin |
| 已推送的提交需要撤销 | git revert <commit> |
| 合并或变基想取消 | git merge --abort 或 git rebase --abort |
| 找最近丢失的提交记录 | git reflog |
| 清理远程已删除的分支记录 | git fetch --prune |
掌握一条基本原则即可避免很多误操作:先看 git status 和 diff,再决定操作;对共享历史优先追加修正,不要轻易重写或强制覆盖。