Appearance
文件状态与跟踪
文件的四种状态
Git 中的文件处于四种状态之一:
┌─────────────────────────────────────────────────────────┐
│ │
│ 未跟踪(Untracked) ──git add──→ 已暂存(Staged) │
│ │ │
│ 未修改(Unmodified) ←──git commit── │ │
│ │ │
│ │──编辑文件──→ 已修改(Modified) ──git add──→ │
│ │
└─────────────────────────────────────────────────────────┘| 状态 | 说明 |
|---|---|
| 未跟踪(Untracked) | 新建文件,Git 不知道它的存在 |
| 未修改(Unmodified) | 已提交,且自上次提交后未发生改动 |
| 已修改(Modified) | 已跟踪文件被修改,但未暂存 |
| 已暂存(Staged) | 修改已添加到暂存区,等待提交 |
git status 查看状态
git status 是使用最频繁的命令之一,显示工作区和暂存区的状态。
bash
git status
# 输出示例:
# On branch main
# Your branch is up to date with 'origin/main'.
#
# Changes to be committed:
# (use "git restore --staged <file>..." to unstage)
# modified: src/auth.js ← 已暂存(将进入下次提交)
# new file: docs/api.md
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git restore <file>..." to discard changes in working directory)
# modified: README.md ← 已修改但未暂存
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# temp.log ← 未跟踪文件简短格式
bash
git status -s
# 或
git status --short
# 输出:
# M src/auth.js ← 暂存区有修改(左列 M)
# M README.md ← 工作区有修改(右列 M)
# A docs/api.md ← 新文件已暂存(A = Added)
# ?? temp.log ← 未跟踪(?? = Untracked)
# D old-file.txt ← 已删除左列表示暂存区状态,右列表示工作区状态:
| 标志 | 含义 |
|---|---|
?? | 未跟踪(Untracked) |
A | 新文件已暂存 |
M | 修改已暂存(左)或已修改未暂存(右) |
D | 删除已暂存(左)或已删除未暂存(右) |
R | 重命名 |
C | 复制 |
U | 冲突未解决 |
git add 暂存文件
git add 将文件添加到暂存区(Index),准备下次提交。
bash
# 暂存单个文件
git add README.md
# 暂存多个文件
git add file1.js file2.js
# 暂存整个目录
git add src/
# 暂存所有修改(包括新文件、修改、删除)
git add .
git add --all
git add -A
# 暂存所有已跟踪文件的修改(不包括新文件)
git add -u区别:git add . vs git add -A vs git add -u
| 命令 | 新文件 | 修改 | 删除 | 范围 |
|---|---|---|---|---|
git add . | ✅ | ✅ | ✅ | 当前目录及子目录 |
git add -A | ✅ | ✅ | ✅ | 整个仓库 |
git add -u | ❌ | ✅ | ✅ | 整个仓库(已跟踪文件) |
注意:在 Git 2.x 中,
git add .和git add -A行为已统一,都处理整个仓库。
git add -p 交互式暂存
-p(patch)模式让你可以只暂存文件的部分内容,是精细化提交的强大工具。
bash
git add -p
# 或
git add --patch交互提示说明
Stage this hunk [y,n,q,a,d,/,s,e,?]?
y - 暂存此块
n - 不暂存此块
q - 退出,不暂存任何剩余内容
a - 暂存此文件的所有块
d - 不暂存此文件的任何块
/ - 搜索匹配正则的块
s - 将当前块分割成更小的块
e - 手动编辑当前块
? - 显示帮助实际使用示例
假设你修改了一个文件,但想分成两次提交(一次是 bug fix,一次是新功能):
bash
git add -p src/app.js
# 对于 bug fix 相关的块,输入 y(暂存)
# 对于新功能相关的块,输入 n(跳过)
git commit -m "fix: 修复空指针异常"
git add src/app.js
git commit -m "feat: 添加用户头像上传功能"git rm 删除文件
从 Git 跟踪和工作区中删除文件。
bash
# 删除文件(同时从工作区和暂存区删除)
git rm README.md
# 只从暂存区删除,保留工作区文件(取消跟踪但不删除文件)
git rm --cached README.md
# 强制删除(已修改或已暂存的文件需要 -f)
git rm -f modified-file.txt
# 删除目录
git rm -r old-directory/
# 使用通配符
git rm '*.log'取消跟踪但保留文件
这在把文件加入 .gitignore 之前已经提交时很有用:
bash
# 取消跟踪 .env 文件(但保留本地文件)
git rm --cached .env
# 添加到 .gitignore
echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: 停止跟踪 .env 文件"git mv 移动/重命名文件
git mv 相当于 mv + git rm + git add 的组合。
bash
# 重命名文件
git mv old-name.js new-name.js
# 移动文件到子目录
git mv app.js src/app.js
# 移动并重命名
git mv old/path/file.js new/path/new-name.jsbash
# 等价的手动操作:
mv old-name.js new-name.js
git rm old-name.js
git add new-name.jsGit 能自动检测重命名(即使通过手动 mv 操作),因为它基于内容相似度来判断。
查看文件详细状态
bash
# 查看工作区中已追踪但未暂存的文件列表
git ls-files -m
# 查看暂存区中的文件列表
git ls-files -s
# 查看未跟踪文件
git ls-files -o --exclude-standard
# 查看被忽略的文件
git ls-files --others --ignored --exclude-standard文件状态流转示例
bash
# 1. 初始状态:创建新文件
echo "Hello" > hello.txt
git status
# Untracked files: hello.txt
# 2. 暂存文件
git add hello.txt
git status
# Changes to be committed: new file: hello.txt
# 3. 提交文件
git commit -m "add hello.txt"
git status
# nothing to commit, working tree clean
# 4. 修改文件
echo "World" >> hello.txt
git status
# Changes not staged for commit: modified: hello.txt
# 5. 暂存修改
git add hello.txt
git status
# Changes to be committed: modified: hello.txt
# 6. 再次提交
git commit -m "update hello.txt"总结
| 操作 | 命令 | 文件状态变化 |
|---|---|---|
| 创建新文件 | — | Untracked |
| 暂存新文件 | git add <file> | Untracked → Staged |
| 提交 | git commit | Staged → Unmodified |
| 修改文件 | 编辑 | Unmodified → Modified |
| 暂存修改 | git add <file> | Modified → Staged |
| 取消暂存 | git restore --staged <file> | Staged → Modified |
| 丢弃修改 | git restore <file> | Modified → Unmodified |
| 删除跟踪 | git rm --cached <file> | Unmodified → Untracked |