一、 命令#
rebase#
rebase 会生成全新的提交哈希,导致本地历史与远程历史产生“分叉”。Git 默认禁止非快进(non-fast-forward)推送,因此必须用强制推送来明确告诉远程:“我要用新历史替换旧历史”。
📖 详细原理拆解#
为什么 rebase 会改写历史?#
Git 中每个提交的唯一标识是一个 SHA 哈希值(如 a1b2c3d)。这个哈希不是随机生成的,而是由以下信息共同计算得出:
提交内容(diff)
作者/提交者信息
时间戳
父提交的哈希值 ← 关键!
当你执行 git rebase main 时,Git 底层实际在做:
把你分支上的提交临时保存为“补丁”
把当前分支指针移到最新的
main逐个重新应用补丁,生成全新的提交
因为新提交的父提交变成了 main 的最新提交,所以即使代码内容一模一样,计算出的哈希值也会全部改变。旧提交并没有被“修改”,而是被新提交替换,历史线因此被重写。
为什么普通 git push 会失败?#
假设远程分支历史是
main: A ─ B ─ C
你的分支: └─ D ─ E (远程记录)
你本地 rebase 后,历史变成了
main: A ─ B ─ C
你的分支: └─ D’─ E’ (本地新哈希,D’/E’ 内容同 D/E 但哈希不同)
当你执行普通 git push 时,Git 会检查:远程分支的末端(E)是不是本地分支末端(E')的祖先?
答案是 否。Git 认为这是一次“非快进更新”,出于防误覆盖的安全机制,会直接拒绝推送并报错:
! [rejected] feature -> feature (non-fast-forward)
为什么必须用强制推送?#
要让远程接受你的新历史,你必须显式覆盖远程的旧引用(ref)。--force 的作用就是告诉 Git:
“我知道历史被改写了,且我确认要用本地的新历史替换远程的旧历史。”
⚠️ 关键安全建议:永远用 --force-with-lease#
git push --force:无脑覆盖。如果在你 rebase 期间有同事刚好推了新提交,你会直接覆盖掉别人的代码,且难以恢复。git push --force-with-lease:带“安全锁”的强推。推送前会检查远程分支自你上次fetch后是否被他人修改。如果被改过,会拒绝推送并提示,保护团队协作安全。这是现代 Git 工作流的强制规范。
使用git rebase合并时遇到冲突时使用git rebase –continue(⚠️不能使用git commit)#
git rebase 是一个批量操作过程,它需要依次应用多个提交。使用 git rebase --continue 是为了告诉 Git:“这个提交的冲突我解决了,请继续应用下一个提交”
二、相关知识#
non-fast-faward(非快进更新)#
🚦 一句话理解「非快进更新」#
快进(Fast-Forward) = 像在时间线上「往后翻书页」,只能向前,不能回头 非快进(Non-Fast-Forward) = 想把书页「撕掉重写」,Git 默认不允许,怕你误删别人的内容
快进推送(安全,默认允许)#
远程 main: A ─ B ─ C
本地 main: A ─ B ─ C ─ D ─ E (你本地多提交了 2 次)
你执行 git push 时,Git 发现:
远程的 C 是你本地 E 的祖先(即你的历史包含远程历史)
→ 只需把 D 和 E「追加」到远程,不修改任何已有提交
→ 这叫 Fast-Forward,Git 放心让你推 ✅
非快进推送(危险,默认拒绝)#
远程 main: A ─ B ─ C ─ F
本地 main: A ─ B ─ C ─ D’ ─ E’ (你 rebase/reset 后,历史分叉了)
你执行 git push 时,Git 发现:
远程的 F 不是 你本地 E' 的祖先,两条历史线「分叉」了
→ 如果要推送,必须覆盖/删除远程的 F 提交
→ 这叫 Non-Fast-Forward,Git 会拦截并报错 ⚠️
CI#
“CI检查"指持续集成(Continuous Integration)过程中的自动化代码检查,是软件开发质量保障的重要环节。
📌 什么是CI检查?#
CI检查是在代码提交或合并时,通过自动化工具对代码进行多维度验证的过程,包括:
✅ 编译构建:确保代码能成功编译
✅ 单元测试:验证功能逻辑正确性
✅ 静态代码分析:检查代码规范、潜在缺陷、安全漏洞
✅ 代码覆盖率:评估测试完整性
✅ 依赖扫描:检测第三方库安全风险
持续集成要求开发人员频繁地将代码集成到共享的主干分支中,每次集成都通过自动化的构建来验证