适用:所有 Linux 耗时:约 40 分钟 前置:T1(会编辑文件)
Git 最常见的错误用法,是把它当成"上传工具"。
它真正解决的是一个问题:我改了东西,怎么退回上一版?
这一篇只讲最小闭环——够你保护自己的文件,不多讲一行。
一、先想清楚:Git 解决什么
没 Git 的时候
报告-最终版.docx
报告-最终版2.docx
报告-最终版-真的最终.docx
报告-最终版-改完待定-20261020.docx
这是所有人都有过的经历。 文件名承载了版本信息,然后就失控了。
有 Git 的时候
报告.docx ← 只有一个文件
历史记录: ← 版本信息在这里
10-20 17:30 改了第三段
10-20 15:00 加了结论
10-19 21:00 初稿
两个核心能力:
- 能退回:任何一次修改都能还原
- 能对比:这次改了什么,一行行看得见
不要被吓到
Git 的命令有几十个。但日常只需要 7 个。
剩下那些(rebase、cherry-pick、bisect)在用不到的时候学,只会增加心理负担。
二、四个概念(用"拍照"来理解)
| 概念 | 类比 | 说明 |
|---|---|---|
| 工作区 | 你正在摆的场景 | 你眼前这些文件 |
| 暂存区(index) | 取景框 | 你决定"这次要拍进去的部分" |
| 本地仓库(.git) | 相册 | 已经拍下来的照片 |
| 远程仓库(remote) | 云相册 | 备份到别处的相册 |
流程:
改文件(工作区)
↓ git add ← 放进取景框
暂存区
↓ git commit ← 按下快门
本地仓库(一张照片 = 一个版本)
↓ git push ← 上传云相册
远程仓库
“暂存区"这个中间层让新手困惑,但它有用:你可以一次改十个文件,但只提交其中三个。这在"改了一大堆但只想提交一部分"时是必需的。
三、七个命令(日常全部)
一次性配置
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
git config --global init.defaultBranch main
git config --global core.editor nano # 免得 commit 时进了 vim 出不来
只做一次。 之后所有仓库通用。
1. git init —— 建仓库
mkdir 我的项目 && cd 我的项目
git init
会在当前目录建一个 .git 隐藏目录,所有历史都存在里面。
2. git status —— 最常用的命令
git status
这个命令你应该用得比所有其他命令加起来还多。
输出告诉你:哪些文件改了、哪些已暂存、当前在哪个分支。
git status -s # 简短版
简短版输出:
M 文件1.txt ← 改了,没暂存
M 文件2.txt ← 改了,已暂存
?? 新文件.txt ← 未跟踪(Git 还没管它)
3. git add —— 放进暂存区
git add 文件.txt # 单个
git add . # 当前目录下所有改动
git add *.py # 按模式
git add -A # 所有改动(含删除)
4. git commit —— 拍下这一版
git commit -m "说明这次改了什么"
-m 后面那句话很重要。 三个月后你只会看到这条信息,“改了"这种说明等于没写。
好的提交信息:
✅ 修复登录页在 Safari 下按钮错位
✅ 补充第三章的练习题(12 道)
❌ 更新
❌ 改了点东西
❌ asdf
一个土办法:写完后问自己"如果只看这句话,能想起改了什么吗”。
跳过暂存直接提交(已跟踪的文件):
git commit -am "说明"
-a 只对"已经跟踪的文件"生效,新建的文件还是要 git add。
5. git log —— 看历史
git log # 完整
git log --oneline # 一行一条(最常用)
git log --oneline -10 # 最近 10 条
git log --oneline --graph # 带分支图
git log -p 文件 # 看某个文件的每次改动内容
6. git diff —— 看改了什么
git diff # 工作区 vs 暂存区(还没 add 的改动)
git diff --staged # 暂存区 vs 上次提交(add 了的改动)
git diff HEAD # 工作区 vs 上次提交(全部改动)
提交前跑一下 git diff --staged,确认这次到底改了什么。这是防止提交垃圾的关键一步。
7. git restore / git reset —— 退回
这是 Git 最有价值的能力,也是最需要小心的。
# 撤销工作区的改动(回到上次提交的状态)⚠️ 改了的东西会没
git restore 文件.txt
# 把文件从暂存区拿出来(改动还在,只是不提交了)
git restore --staged 文件.txt
# 撤销最近一次提交,但保留改动
git reset --soft HEAD~1
# 撤销最近一次提交,且丢弃改动 ⚠️⚠️
git reset --hard HEAD~1
⚠️
git restore 文件和git reset --hard会永久丢弃未提交的改动。 没有回收站。 用之前先git status和git diff看清楚。
救命的一招:如果你 reset --hard 删错了,还能找回来(只要没被 Git 清理):
git reflog # 看所有 HEAD 移动记录
git reset --hard HEAD@{2} # 回到两步之前
git reflog 是 Git 的"后悔药”。 记住这个命令,能救很多次。
四、.gitignore:别把垃圾也提交
有些文件不该进版本库:
- 编译产物(
*.o、*.pyc、build/) - 依赖目录(
node_modules/、venv/) - 密钥和密码(
*.key、.env)← 这条最重要 - 系统文件(
.DS_Store、Thumbs.db) - 临时文件(
*.log、*.tmp)
在项目根目录建 .gitignore:
# 编译产物
*.o
*.pyc
__pycache__/
build/
dist/
# 依赖
node_modules/
venv/
.venv/
# 密钥和配置(千万不能提交)
*.key
*.pem
.env
config.local.*
# 系统垃圾
.DS_Store
Thumbs.db
# 日志和临时
*.log
*.tmp
⚠️ 已经提交过密钥怎么办:
git rm --cached 文件只从 Git 移除,但历史里还在。 正确的做法是立刻把那个密钥作废、重新生成。 历史清理很麻烦,而且如果不 push 到公网还好,一旦推上去就当泄露处理。
五、连接远程仓库(GitHub / Gitee / 自建)
方式一:HTTPS + 令牌(简单)
git remote add origin https://github.com/用户名/仓库名.git
git push -u origin main
现在 GitHub 不支持密码,要用 Personal Access Token(PAT)当密码。
方式二:SSH(推荐,配一次永久免密)
复用 T3 的密钥:
# 看有没有现成的公钥
cat ~/.ssh/id_ed25519.pub
复制输出,粘到 GitHub → Settings → SSH and GPG keys → New SSH key。
验证:
ssh -T git@github.com
# 应该看到 "Hi 用户名! You've successfully authenticated..."
然后:
git remote add origin git@github.com:用户名/仓库名.git
git push -u origin main
四个远程命令
git remote -v # 看当前配的远程地址
git push # 推上去
git pull # 拉下来(= fetch + merge)
git clone 地址 # 克隆一整个仓库
首次 push 要 -u(git push -u origin main),之后直接 git push。
六、分支:最小用法
分支 = 平行世界。 你可以在分支上乱改,不影响主分支。
日常只需要三个命令:
git branch # 看有哪些分支
git switch -c 新分支名 # 建并切过去
git switch main # 切回主分支
合并:
git switch main
git merge 新分支名
新手先不学分支也完全没问题。 一个人写文档/小项目,直接在
main上提交就够。 分支是"多人协作"和"做实验性改动"时才需要的。
七、一个完整的实战流程
假设你要管理一个文档项目。
# ===== 第一次 =====
mkdir 我的文档 && cd 我的文档
git init
git config user.name "张三" # 只在仓库内有效
git config user.email "zhang@x.com"
# 建 .gitignore
cat > .gitignore << 'EOF'
*.log
*.tmp
.DS_Store
EOF
# 写第一个文件
echo "# 我的文档" > README.md
# 第一次提交
git add .
git status # 确认要提交什么
git commit -m "初始化项目"
# ===== 日常 =====
# 改文件
nano README.md
# 看改了什么
git status
git diff
# 提交
git add README.md
git commit -m "补充项目说明"
# 看历史
git log --oneline
这就是 90% 的日常用法。
八、四个真实场景
场景 1:改坏了,想退回
git status # 看哪个文件改了
git diff 那个文件 # 确认改了什么
git restore 那个文件 # 退回 ⚠️ 改动会丢
场景 2:提交了但信息写错了
git commit --amend -m "正确的说明"
只改最近一次,且还没 push 的情况。
场景 3:提交了不该提交的文件
# 如果刚提交、还没 push
git rm --cached 文件
git commit --amend -m "移除误提交的文件"
场景 4:想看某个文件的历史
git log --oneline -- 文件名
git log -p -- 文件名 # 带每次的改动内容
九、动手:五个练习
练习 1:建仓库并提交
mkdir -p /tmp/gitlab && cd /tmp/gitlab
git init
git config user.name "测试"
git config user.email "test@test.com"
echo "第一版" > a.txt
git add a.txt
git status
git commit -m "第一次提交"
git log --oneline
练习 2:改文件、看 diff、提交
echo "第二版" > a.txt
git diff # 看改动
git add a.txt
git diff --staged # 看暂存的内容
git commit -m "改成第二版"
git log --oneline
练习 3:退回上一版
echo "第三版" > a.txt
cat a.txt # 第三版
git restore a.txt # 退回
cat a.txt # 变回第二版
# 已经提交的退回
echo "第四版" > a.txt
git add a.txt && git commit -m "第四版"
git reset --hard HEAD~1 # ⚠️ 退回上次提交
cat a.txt # 第二版
练习 4:用 reflog 找回
git reflog # 看所有移动记录
git reset --hard HEAD@{1} # 回到刚才那步
cat a.txt # 第四版回来了
这个练习很重要——亲手体验"删了还能救回来"。
练习 5:.gitignore 生效
echo "secret" > password.key
echo "*.key" > .gitignore
git status # password.key 不该出现
git add .
git commit -m "加 gitignore"
十、验证:你过关了吗
- 会
git init/add/commit/status/log/diff - 知道暂存区是干什么的
- 会写有意义的提交信息
- 会用
git restore退回未提交的改动 - 会用
git reflog找回误删的提交 - 会写
.gitignore,知道密钥不能提交 - 会
git remote add+git push
十一、不行怎么办
Q1:fatal: not a git repository
当前目录不是仓库。cd 到有 .git 的目录,或者先 git init。
Q2:Please tell me who you are
没配用户名邮箱:
git config --global user.name "名字"
git config --global user.email "邮箱"
Q3:git commit 时进了 vim,出不来
Esc 然后 :wq。预防:
git config --global core.editor nano
Q4:push 报 rejected (non-fast-forward)
远程有你本地没有的提交(常见于网页上直接改过)。先拉:
git pull --rebase
git push
Q5:push 要密码,输密码又不对
GitHub 已不支持账号密码。用 Personal Access Token 代替密码,或者改用 SSH(推荐)。
Q6:Permission denied (publickey)
SSH 密钥没配好。见 T3 SSH 的排障部分,然后验证:
ssh -T git@github.com
Q7:提交了很大的文件,push 很慢
git rm --cached 大文件
echo "大文件" >> .gitignore
git commit -m "移除大文件"
但历史里还在,仓库依然大。要彻底清需要用 git filter-repo(高级话题,先不用碰)。
Q8:把整个项目搞乱了,想重来
ls -a # 确认有 .git
rm -rf .git # ⚠️ 删掉所有历史
git init # 重新开始
这会丢失全部历史。 确认不要了再动手。
十二、一句话总结
Git 解决的是"能退回",不是"能上传"。
日常 7 个命令:
init/status/add/commit/log/diff/restore。救命命令:
git reflog。
.gitignore第一条规矩:密钥永远不进仓库。
← 上一篇 T4|文件传输 下一篇 → T6|软件源:为什么装不上