【Git 避坑系列·下篇】代码丢了怎么救?`.gitignore` 不生效怎么办?这 5 个高频坑一次讲透
在实际开发里,很多 Git 问题不是“不会用”,而是“知道一点但边界不清楚”。
高频事故通常就这几类:
-
reset --hard后改动消失 -
stash恢复代码时冲突 -
.gitignore写了却不生效 - 冲突标记不知道怎么处理
- 协作时一次
--force覆盖他人提交
上篇我们讲了提交规范、分支管理、rebase/merge。这篇聚焦“救火场景”,给你一套能直接落地的处理方法。
1)`reset` 和 `revert`:都是“撤销”,但语义完全不同
很多翻车来自一句话:“我只是想撤销一下提交。”
但如果命令选错,后果差异会非常大。先看对照表:
| 命令 | 实际行为 | 代码改动 | 是否改写历史 | 推荐场景 |
|---|---|---|---|---|
git revert |
新增一条“反向提交” | ✅ 保留 | ❌ 否 | 已 push 的提交回退 |
git reset --soft |
回退提交到暂存区 | ✅ 保留 | ✅ 是 | 本地整理提交 |
git reset --mixed |
回退提交到工作区 | ✅ 保留 | ✅ 是 | 本地重新拆分提交 |
git reset --hard |
回退并清空工作区改动 | ❌ 丢失 | ✅ 是 | 高危命令,谨慎使用 |
场景 A:刚提交,发现 message 写错
git commit --amend -m "fix: 修复登录态过期后未重定向的问题"
说明:仅建议用于尚未 push 的提交。
场景 B:刚提交,还想继续改
# 回退到暂存区
git reset --soft HEAD~1
# 回退到工作区(更常用)
git reset HEAD~1
场景 C:提交已经 push,需要撤销
git log --oneline
git revert <commit-hash>
git push
说明:团队协作优先 revert,因为它不改写公共历史。
场景 D:误用 `reset –hard`,还能恢复吗?
可以先看 reflog:
git reflog
# 找到误操作前那次 HEAD
git checkout -b recover-branch <hash>
关键结论:代码误删先别慌,第一步先查 reflog。
2)`stash`:不是只有 `push` / `pop`
stash 的本质是“临时封存当前工作现场”。
用得好是救场神器,用不好是冲突放大器。
常用命令
# 暂存并附带说明
git stash push -m "feat/user-avatar 开发中断点"
# 查看列表
git stash list
# 取最近一条并移除
git stash pop
# 取指定一条但保留
git stash apply stash@{1}
# 删除某条 / 清空
git stash drop stash@{0}
git stash clear
高频坑位
坑 1:新文件没进 stash
默认 git stash 不包含未追踪文件,需使用:
git stash -u
坑 2:stash pop 冲突后,stash 还在
冲突时不会自动删除 stash,需要你手动 drop。
更稳恢复方案:从 stash 直接起分支
git stash branch fix/hotfix-from-stash stash@{0}
优点:隔离恢复环境,通常比在当前分支 pop 更安全、冲突更少。
3)`.gitignore` 为什么“不生效”?
一句话解释:
.gitignore只对“尚未被 Git 追踪”的文件生效。
如果文件已经被 add / commit 过,再写 ignore 规则不会自动取消追踪。
正确处理流程:
# 取消追踪,但保留本地文件
git rm --cached .env
# 目录同理
git rm -r --cached node_modules/
git commit -m "chore: stop tracking env and dependencies"
前端项目常用 `.gitignore` 模板
# dependencies
node_modules/
# build outputs
dist/
build/
.next/
# env
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
# system
.DS_Store
Thumbs.db
# logs
*.log
安全提醒(必须重视)
如果 .env 曾经 push 到远端,即使后续删除,敏感信息可能仍存在于历史提交中。
建议动作:
- 立刻轮换密钥(数据库、云服务、第三方 API)
- 排查访问日志与调用记录
- 评估是否需要历史清理(如
git filter-repo)
4)冲突处理:按标准 5 步走,别硬慌
冲突不是错误,本质是“同一位置存在不同改动,需要人工决策”。
冲突标记示例
<<<<<<< HEAD
const name = "张三";
=======
const name = "李四";
>>>>>>> feat/user-profile
解释:
-
HEAD上方:当前分支内容 - 分隔线下方:待合并分支内容
标准处理流程
-
git status定位冲突文件 - 打开文件并决定保留方案(A/B/融合)
- 删除冲突标记(
<<<<<<<` / `=======` / `>>>>>>>) -
git add标记冲突已解决 - 执行
git merge --continue或git rebase --continue
降低冲突概率的 3 个习惯
- 分支开发期间定期同步主干
- 控制功能分支生命周期,不要长期堆积
- 同模块并行开发前先沟通改动边界
5)团队协作中的高风险动作
5.1 强推优先用 `–force-with-lease`
# ❌ 高风险(可能直接覆盖他人提交)
git push --force
# ✅ 更安全(远端有新提交会拒绝覆盖)
git push --force-with-lease
5.2 PR 前自检清单
x本地构建/测试通过
x已同步主干并解决冲突
xcommit message 清晰可读
xPR 描述包含:改了什么、为什么改、如何验证
x无调试残留(console.log、断点、临时注释)
x无无关文件改动
5.3 常用全局配置
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
# 团队确认后可启用
git config --global pull.rebase true
# 常用别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.lg "log --oneline --graph --all --decorate"
5.4 清理废弃分支
git fetch --prune
git branch --merged develop
git branch --merged develop | grep -v "develop|main|master" | xargs git branch -d
速查清单(建议保存)
A. 撤销操作怎么选
- 已 push:
git revert - 未 push 且想重提:
git reset --mixed HEAD~1 - 误删恢复:
git reflog→git checkout -b recover
B. `stash` 安全用法
- 存:
git stash push -m "desc" - 含新文件:
git stash -u - 稳妥恢复:
git stash branch stash@{0}
C. `.gitignore` 不生效处理
- 先取消追踪:
git rm --cached - 再提交 ignore 规则
这些技巧都不“高深”,但非常“高频”。掌握后能显著降低 Git 事故概率。
最后建议:不确定时先在测试仓库演练,再在正式仓库执行。
更多《软件安装&避坑&实践》系列
关注公众号:IT安装手册
博客:https://itinstall.dev