一口气解决 10 个 Git 高频坑:CRLF 警告、push 被拒、撤回 git add、子模块等

基于实际项目踩坑总结,配好命令就能复现/修复。涵盖跨平台换行符、非快进推送、撤回暂存、回滚提交、.gitignore、子模块、合并冲突、Detached HEAD、大文件(LFS)与提交规范。

Git工作流示意


1. 场景说明与版本建议

  • 适用人群:日常用 Git 协作/提交代码的开发者
  • 建议版本git --version ≥ 2.30(支持 git restore 等新命令)
  • 推荐工具:命令行 + 可视化(GitKraken / SourceTree / VS Code Git)

2. 高频坑 #1:CRLF/LF 警告与跨平台协作

症状

  • Windows 上提示:LF will be replaced by CRLF
  • macOS/Linux 提示:CRLF will be replaced by LF

原因
不同平台的换行符不一致(Windows=CRLF,类 Unix=LF)。

仓库级配置(推荐)

# Windows
git config core.autocrlf true
# macOS / Linux
git config core.autocrlf input

更稳的做法:用 .gitattributes 固定文本行为

# 统一文本文件为 LF,自动规范化
* text=auto eol=lf

# 保持二进制原样
*.png binary
*.jpg binary
*.pdf binary

把已有文件按规则重新规范化

git add --renormalize .
git commit -m "chore: normalize line endings via .gitattributes"

提示:团队统一 .gitattributescore.autocrlf,新同学入场可避免重复警告。


3. 高频坑 #2:push 被拒(非快进,远端有更新)

症状

  • ! [rejected] main -> main (non-fast-forward)
  • 提示需要先拉取远端更新

安全做法:先 rebase 再推送

git fetch origin
git pull --rebase origin main
# 解决冲突后
git push origin main

不想 rebase,用合并也可

git pull origin main   # 生成一个 merge commit
git push origin main

避免覆盖他人历史,谨慎使用:

# 仅在你明确需要强推且团队允许时
git push --force-with-lease

4. 高频坑 #3:撤回 git add(把已暂存的文件退回工作区)

单个文件

git restore --staged path/to/file
# 旧写法(兼容)
git reset HEAD path/to/file

全部文件

git restore --staged .

顺手纠错git add . 添加当前目录;git add -A 添加所有变更(含删除)。
git add .. 是添加父目录,不是“全部文件”。


5. 高频坑 #4:撤销最近一次提交(区分保留/丢弃改动)

保留改动,只撤销提交记录

git reset --soft HEAD~1
# 文件仍然保留在暂存区

撤销提交并把改动放回工作区

git reset --mixed HEAD~1
# 等价于:git reset HEAD~1

彻底回退(连改动也丢弃,危险)

git reset --hard HEAD~1

已推送到远端的提交,请用 Revert(更安全)

git revert <commit_sha>
git push origin main

6. 高频坑 #5:.gitignore 不生效(文件已被追踪)

步骤

  1. 把路径写入 .gitignore
  2. 从索引中移除已追踪文件(不删工作区)
    git rm -r --cached dist/ logs/ .idea/
    git commit -m "chore: stop tracking build & IDE artifacts"
    
  3. 以后再提交就会忽略

全局忽略(本机 IDE 文件等)

git config --global core.excludesfile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global

7. 高频坑 #6:子模块初始化/更新失败

初始化与递归拉取

git submodule update --init --recursive

让子模块 URL 与父仓一致(换源/换协议后)

git submodule sync --recursive

在所有子模块中执行命令

git submodule foreach --recursive 'git checkout main && git pull'

常见报错

  • does not have a commit checked out:进入子模块目录,git checkout <branch>,再回父仓更新。
  • 权限问题:确认子模块远端地址与凭据(HTTPS/SSH)一致。

8. 高频坑 #7:合并冲突与安全回滚

遇到冲突的基本流程

# 定位冲突文件并手工编辑 <<< === >>>
git status

# 解决后标记已解决
git add path/to/conflicted_file
git commit

放弃本次合并/变基

git merge --abort
git rebase --abort

可视化排障

git log --oneline --graph --decorate -n 20

建议在合并前 git fetch && git rebase,减少冲突面。


9. 高频坑 #8:Detached HEAD(游离头指针)

症状
在某个 commit/tag 上检出并做了修改,提示你处于 Detached HEAD。

修复
把当前状态保存为分支:

git switch -c fix/work-on-detached-head
git push -u origin fix/work-on-detached-head

10. 高频坑 #9:仓库过大/二进制文件膨胀(用 Git LFS)

为大文件开启 LFS

# 一次性安装(每台机器)
git lfs install

# 指定需要 LFS 管理的后缀
git lfs track "*.psd"
git lfs track "*.zip"
echo "*.psd filter=lfs diff=lfs merge=lfs -text" >> .gitattributes

git add .gitattributes
git commit -m "chore: enable Git LFS for binaries"

已有历史很大?
BFG Repo-Cleaner / git filter-repo 清理历史(破坏性操作,谨慎,先备份)。


11. 高频坑 #10:提交信息规范与常用 alias

提交信息建议(Conventional Commits)

feat: 新增打印任务的计费逻辑
fix: 修复 Windows 下路径分隔符导致的崩溃
docs: 补充 README 的安装说明
chore: 更新依赖或构建脚本
refactor: 重构,不改变外部行为

常用 alias

git config --global alias.co "checkout"
git config --global alias.br "branch -vv"
git config --global alias.cm "commit -m"
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate --all"

12. 常用命令清单(可直接复制)

# 统一换行符策略(仓库级)
git config core.autocrlf true   # Windows
git config core.autocrlf input  # macOS/Linux

# 非快进推送:安全拉取
git fetch origin
git pull --rebase origin main
git push origin main

# 撤回已暂存(staged)
git restore --staged path/to/file

# 回滚最近一次提交(保留改动)
git reset --soft HEAD~1

# .gitignore 生效(停止追踪)
git rm -r --cached dist/
git commit -m "chore: stop tracking dist/"

# 子模块
git submodule update --init --recursive
git submodule sync --recursive

# 合并/变基中断
git merge --abort
git rebase --abort

# 从 Detached HEAD 建分支
git switch -c fix/work-on-detached-head

13. FAQ

Q:如何只提交已跟踪文件的变更(不包含新文件)?
A:git add -ugit commit -a -m "msg"

Q:如何只把当前目录的改动加到暂存区?
A:git add .(注意不是 git add ..)。

Q:如何查看某文件的历史并回到旧版本?
A:git log -- path/to/file,抄下 SHA,git checkout <sha> -- path/to/file


14. 结语 & 互动

  • 把你最常见的一条 Git 报错原文贴在评论里,我给你“一行命令”的修复建议。
  • 需要把本文整理成「速查 PDF」吗?评论区留「要 PDF」,我就出。

CRLF/LF与.gitattributes规范化示意rebase/merge 流程对比


SEO 关键词:Git 错误、CRLF、撤回 git add、non-fast-forward、子模块、合并冲突、Detached HEAD、Git LFS、提交信息规范、Git 命令速查

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐