03. add/commit/push 别再死记:Git 工作流核心概念实操

「Git」系列已发布: 00. 改崩代码不敢回退?Git 版本控制 3 分钟救你狗命 | 01. Git 装完不会配?Windows/macOS/Linux 三端配置一次到位 | 02. Git 配置总踩坑?全局/仓库/SSH 密钥一次搞懂 | 03. add/commit/push 别再死记:Git 工作流核心概念实操(本文)

工作区、暂存区、本地仓库三层关系没搞懂,Git 命令永远背不熟。本文用实操串起基本工作流,让你真正理解每一步在干什么。

一、初始化仓库

Git 仓库有两个来源:从零初始化,或者 clone 一个已有的。

1.1 git init:从零开始

# 建项目目录
mkdir my-project
cd my-project
# 初始化
git init
# 输出:Initialized empty Git repository in /path/to/my-project/.git/
# 看看 .git 目录里有什么
ls -la .git/
# HEAD  config  description  hooks/  info/  objects/  refs/

git init在当前目录下创建.git子目录——这就是仓库的核心,所有版本历史、配置、分支信息都在里面。

除此之外项目其他文件仍在工作目录中,Git 还没开始跟踪它们。

1.2 git clone:从远程拿

# HTTPS
git clone https://github.com/user/repository.git
# SSH
git clone git@github.com:user/repository.git
# 克隆到指定目录名
git clone https://github.com/user/repository.git my-local-name
# 浅克隆——只拿最新提交,不要历史,适合大型仓库快速取代码
git clone --depth 1 https://github.com/user/repository.git

会把远程仓库完整复制到本地——所有提交历史、全部分支和标签。
克隆完成后 Git 自动把远程仓库命名为origin,并将默认分支(main/master)检出到工作目录。

1.3 文件状态与生命周期

回到第 00 篇讲的三区模型。Git 里每个被跟踪的文件都处于四种状态之一:

stateDiagram-v2 [*] --> Untracked : 新建文件 Untracked --> Staged : git add Staged --> Unmodified : git commit Unmodified --> Modified : 编辑文件 Modified --> Staged : git add Modified --> Unmodified : git restore(丢弃修改) Staged --> Modified : git restore --staged(取消暂存)

操作对应关系:

# 查看当前仓库状态——这是使用频率最高的 Git 命令
git status
# 三种典型输出:
# 1. Untracked files: 新文件,从未被 git add 过
# 2. Changes not staged for commit: 已跟踪文件有修改,但没暂存
# 3. Changes to be committed: 已暂存,等 commit

1.3.1 git add:把修改放进暂存区

# 单个文件
git add README.md
# 多个特定文件
git add src/main.py src/utils.py
# 当前目录及子目录下所有修改
git add .
# 整个工作目录所有修改(含删除)
git add -A
# 交互式——分块选要暂存的内容
git add -p

git add -p容易被忽略但极其好用。它会逐块展示未暂存的修改,让你选怎么处理:

(1/2) Stage this hunk [y,n,q,a,d,e,?]?
  • y— 暂存这一块
  • n— 不暂存这块
  • q— 退出
  • a— 暂存这块以及当前文件里所有后续块
  • d— 不暂存这块及后续
  • e— 手动编辑这块

1.4 git rm 与 git mv

# 从版本库和工作目录都删掉
git rm old_file.txt
# 只从版本库删,保留工作目录文件
git rm --cached secret_config.yml
# 移动/重命名(Git 会自动检测)
git mv old_name.py new_name.py

1.5 提交修改

commit 是把暂存区的内容永久写进版本历史。

每次提交生成一个全局唯一的 SHA-1 校验和,附带作者、时间戳和提交说明。

1.5.1 基本操作

# 标准提交
git commit -m "添加用户登录功能"
# 跳过暂存区,直接提交所有已跟踪文件的修改
git commit -a -m "修复导航栏样式问题"
# 修改上一次提交(追加修改或改信息)
git commit --amend -m "修正提交信息"

1.5.2 提交信息怎么写

好的 commit message 对团队协作和项目维护非常重要。推荐格式:

<type>(<scope>): <subject>
<body>
<footer>
字段 说明 示例
type 提交类型 feat / fix / docs / style / refactor / test / chore
scope 影响范围(可选) auth / api / ui
subject 简短描述(50 字以内) 添加 JWT 令牌刷新机制
body 详细说明(每行 72 字以内) 说明为什么改、和之前行为的对比
footer 关联信息 Closes #123 / BREAKING CHANGE

示例:

(auth): 添加双因素认证支持
用户在登录后需要输入 6 位动态验证码才能完成认证。
新增接口:

- POST /api/auth/2fa/enable  启用双因素认证
- POST /api/auth/2fa/verify  验证动态码
Closes #456

1.6 查看历史

Git 的日志功能相当丰富,下面是我日常最常用的组合:

# 基本日志
git log
# 紧凑格式(一行一条)
git log --oneline
# 最近 N 条
git log -5
# 图形化分支历史
git log --oneline --graph --decorate --all
# 按作者
git log --author="Zhang San"
# 按时间范围
git log --since="2026-07-01" --until="2026-07-29"
# 按提交信息关键词
git log --grep="修复"
# 某个文件的修改历史
git log -p -- src/main.py
# 某次提交的详细变更
git show a3f2b1c
# 统计每次提交的变更量
git log --stat

1.6.1 自定义日志格式

# 高度自定义输出
git log --pretty=format:"%C(yellow)%h%Creset - %C(cyan)%ad%Creset : %s %C(green)(%an)%Creset" --date=short
# 占位符说明:
# %h  缩写提交哈希
# %H  完整提交哈希
# %an 作者名字
# %ae 作者邮箱
# %ad 作者日期(受 --date 影响)
# %s  提交标题

1.7 撤销操作

撤销是日常最常用的操作,也是新手容易丢数据的地方。按场景分类说一下。

1.7.1 撤销工作目录的修改

# 丢弃某个文件的未暂存修改,恢复到最近一次提交的状态
git checkout -- file.txt
# 新版写法(语义更清晰)
git restore file.txt
# 丢弃所有未暂存修改
git restore .

1.7.2 撤销暂存区

# 从暂存区移除,保留工作目录的修改
git reset HEAD file.txt
# 新版写法
git restore --staged file.txt

1.7.3 撤销提交

# 撤销最近一次提交,修改留在工作目录(最常用)
git reset --soft HEAD~1
# 撤销最近一次提交,修改保留但不暂存
git reset --mixed HEAD~1
# 完全撤销——修改也丢掉
git reset --hard HEAD~1
# 创建一个新提交来"反做"某次提交(安全,可追溯)
git revert a3f2b1c

resetvsrevert:核心区别

操作 历史影响 安全性 什么时候用
git reset 重写历史 低(已推送的分支慎用) 本地提交修正
git revert 追加新提交 高(无损) 已推送的公共分支

1.8 忽略文件

项目里总有不需要纳入版本控制的文件——编译产物、依赖目录、环境配置、IDE 文件等。

1.8.1 .gitignore

在项目根目录创建.gitignore:


# 二、依赖目录
node_modules/
vendor/
__pycache__/

# 三、编译产物
*.pyc
*.class
dist/
build/

# 四、环境配置
.env
.env.local
*.local

# 五、IDE
.vscode/
.idea/
*.swp
*.swo

# 六、操作系统
.DS_Store
Thumbs.db

# 七、日志
*.log
logs/

# 八、但保留 logs 目录本身(加 .gitkeep)
!logs/.gitkeep

1.8.2 .gitignore 规则

  • 每行一条规则,#开头是注释。
  • 以/开头表示从仓库根目录匹配。
  • 以/结尾表示匹配目录。
  • !取反,重新包含被排除的文件。
  • *匹配除/外的任意字符,**匹配任意路径。

1.9 全局 .gitignore

# 创建全局忽略文件
touch ~/.gitignore_global
# 让 Git 用它
git config --global core.excludesfile ~/.gitignore_global
# 加入系统级忽略规则
echo ".DS_Store" >> ~/.gitignore_global
echo "Thumbs.db" >> ~/.gitignore_global

1.10 文章引用

📌 本文首发于微信公众号 【运维知识点滴】——专注运维实战干货,微信搜索“运维知识点滴”或扫下方二维码关注,更新不迷路。
📎 微信原文:03. add/commit/push 别再死记:Git 工作流核心概念实操

微信公众号【运维知识点滴】 微信小程序【A5单据合并&大试卷拆分转A4打印】
运维实战干货 · 关注追更 Word 转 PDF · 试卷/发票打印神器 · 免费
运维实战干货 · 关注追更 Word 转 PDF · 试卷/发票打印神器 · 免费

💡 小程序【A5单据合并&大试卷拆分转A4打印】是干嘛的? 一个 Word 转 PDF 的打印神器,专治“文档版式和打印机对不上”:

  • A3 试卷打不出来? 学校发的电子版试卷多是 A3,家用打印机只吃 A4——上传 Word 一键转换:可缩到一页 A4(页数不变),也可对半拆成两张 A4(1:1 原大、字更清晰),两种模式自选;
  • 版式不乱:真实渲染引擎原样转换、绝不重排内容,转出的 PDF 和原 Word 排版一致,公式/表格/图片不跑版;
  • 两张 A5 单据拼一张 A4:出租车票、火车票等报销凭证拼版后,一次打印、整齐粘贴;
  • 隐私省心:无需注册,转换结果留存 5 天、最多下载 5 次即自动删除,不留任何历史记录;
  • 微信扫码即用,免费、免安装,支持 doc / docx(≤50MB)。

上一篇:02. Git 配置总踩坑?全局/仓库/SSH 密钥一次搞懂