news 2026/4/21 10:31:29

为什么你的 PR 总是多出一堆奇怪的 commit?90% 的人都踩过这个 Git 坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么你的 PR 总是多出一堆奇怪的 commit?90% 的人都踩过这个 Git 坑

为什么你的 PR 总是多出一堆奇怪的 commit?90% 的人都踩过这个 Git 坑

在日常开发中,功能分支开发周期较长时,主干分支往往已经有了新的提交。这时需要将主干的最新代码同步到自己的功能分支,常见的方式有两种:mergerebase。本文通过实际场景对比两种方式的区别与使用方法。


背景:为什么需要同步主干?

假设你从主干main切出了功能分支feature/my-work,开发过程中主干有了新的提交,此时你的分支历史如下:

main: A ── B ── C(新提交) feature: A ── B ── D(你的提交)

如果不同步主干,提 PR 时可能产生冲突,或者遗漏主干的重要修改。


git pull 是什么?

git pullgit fetch+ 合并操作的快捷命令,默认使用 merge 方式:

gitpull origin main# 等价于gitfetch origingitmerge origin/main

也可以指定使用 rebase 方式:

gitpull--rebaseorigin main# 等价于gitfetch origingitrebase origin/main

两者的区别与下文 merge / rebase 章节一致。如果希望git pull始终使用 rebase,可以设置全局配置:

gitconfig--globalpull.rebasetrue

💡建议:对于个人功能分支,推荐全局开启pull.rebase true,保持提交历史线性整洁。


方式一:merge

原理

将主干的最新提交合并进你的分支,并生成一个新的MergeCommit记录这次合并。

main: A ── B ── C \ feature: A ── B ── D ── M(MergeCommit)

操作步骤

第一步:拉取远程最新代码

gitfetch origin

第二步:切换到自己的功能分支

gitcheckout feature/my-work

第三步:合并主干

gitmerge origin/main

处理冲突(如有)

# 手动解决冲突后gitadd.gitmerge--continue# 放弃本次合并gitmerge--abort

第四步:推送到远程

gitpush origin feature/my-work

提 PR 后的 commit 记录

D 你的提交 M Merge branch 'origin/main' into feature/my-work

方式二:rebase(推荐)

原理

将你的提交「移植」到主干最新提交的后面,历史记录保持线性,不会产生多余的 MergeCommit

main: A ── B ── C \ feature: A ── B ── C ── D'(你的提交被接在 C 后面)

操作步骤

第一步:拉取远程最新代码

gitfetch origin

第二步:切换到自己的功能分支

gitcheckout feature/my-work

第三步:变基到主干

gitrebase origin/main

处理冲突(如有)

rebase 会逐个回放你的每一个 commit,每个 commit 都可能产生冲突,需要逐一处理:

# 手动解决冲突后gitadd.gitrebase--continue# 放弃本次 rebasegitrebase--abort

第四步:force push 到远程

由于 rebase 改写了本地提交历史,必须使用 force push 同步到远程:

gitpush origin feature/my-work --force-with-lease

⚠️为什么用--force-with-lease而不是--force
--force会无条件覆盖远程分支,存在覆盖他人提交的风险。
--force-with-lease更安全——如果远程分支有你本地没有的新提交,会拒绝推送并提示,避免意外覆盖他人代码。

提 PR 后的 commit 记录

D' 你的提交(仅此一条,干净清晰)

两种方式对比

mergerebase
历史记录非线性,含 MergeCommit线性,简洁清晰
PR commit 数量自己的 commit + MergeCommit只有自己的 commit
推送方式正常git pushgit push --force-with-lease
冲突处理次数只处理一次每个 commit 都可能处理一次
适合场景多人协作的公共分支个人功能分支同步主干

常见问题

Q:rebase 时提示hint: use --reapply-cherry-picks to include skipped commits

这是正常现象。rebase 检测到你分支上的某个 commit 内容已经存在于目标分支(例如之前被 cherry-pick 过),会自动跳过该 commit,避免重复提交。

可以关闭这条提示:

gitconfig--globaladvice.skippedCherryPicksfalse

Q:rebase 之后提 PR,为什么还是有重复的 commit?

rebase 只改写了本地历史,如果没有执行 force push,远程分支仍然是旧的历史。PR 提的是远程分支,所以重复的 commit 还是会被带进去。

务必在 rebase 完成后执行:

gitpush origin feature/my-work --force-with-lease

Q:git pull默认是 merge,能改成 rebase 吗?

可以,设置全局配置:

# git pull 默认使用 rebasegitconfig--globalpull.rebasetrue

设置后,git pull等价于git pull --rebase,不再产生多余的 MergeCommit。


总结

  • 个人功能分支同步主干,推荐使用rebase,PR 历史干净,只包含自己真正新增的 commit。
  • 公共分支之间的合并,推荐使用merge,保留完整历史,不需要 force push,更安全。
  • 无论哪种方式,同步前都应先执行git fetch origin获取远程最新状态。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 10:27:24

用ESP8266和IRremoteESP8266库,把旧空调改造成智能空调(附完整代码)

用ESP8266和IRremoteESP8266库打造智能空调控制器 家里的老空调还在兢兢业业工作,但每次都要找遥控器实在麻烦?通过ESP8266开发板和IRremoteESP8266库,我们可以轻松将传统空调升级为支持手机远程控制的智能设备。这个项目不仅成本低廉&#x…

作者头像 李华
网站建设 2026/4/21 10:24:32

魔兽争霸III焕然一新:用WarcraftHelper插件解决8大经典痛点

魔兽争霸III焕然一新:用WarcraftHelper插件解决8大经典痛点 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸III在老电脑上卡…

作者头像 李华
网站建设 2026/4/21 10:24:06

WeChatExporter:你的微信记忆守护者,一键解锁被封存的聊天时光

WeChatExporter:你的微信记忆守护者,一键解锁被封存的聊天时光 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 还记得那些深夜的长谈吗&#xff1…

作者头像 李华
网站建设 2026/4/21 10:23:39

CI/CD—可持续发布relaeas,apk——无相无界(2)—东方仙盟

自动构建CI/CD yml脚本Continuous Integration / Continuous Deployment 发布到releasename: Build & Upload to Releaseon:push:branches: [ main ]workflow_dispatch:jobs:build:runs-on: ubuntu-latestpermissions:contents: writesteps:- uses: actions/checkoutv4- n…

作者头像 李华