`git pull` 和 `git pull --rebase origin master` 的本质区别 git pull和git pull --rebase origin master的本质区别在于当本地分支与远程分支发生分叉即两边都有新的提交时它们合并代码的“底层机制”和“提交历史演变”完全不同。要理解它们的本质区别我们首先要明白git pull实际上是一个组合命令git pullgit fetchgit mergegit pull --rebasegit fetchgit rebase以下是它们的核心区别和底层逻辑1. 默认的git pull基于git merge本质是三方合并Three-way Merge。当你在本地做了一些提交同时别人也向远程master提了代码此时执行git pull工作原理Git 会找到两边的公共祖先提交然后将远程的新提交和本地的新提交“强行合并”。生成物会在本地自动生成一个新的“Merge commit”合并提交。这个提交会有两个父节点用来把两条分叉的历史重新拧到一起。历史线索保留了完整的、真实的团队开发交织的时间线但也因为存在大量的 “Merge branch ‘master’ of …” 节点导致 Git 历史变成一张错综复杂的网常常被称为“麻花线”。2.git pull --rebase基于git rebase本质是变基Rebase即重写提交历史。在同样的场景下如果你执行git pull --rebase origin master工作原理Git 会先把你本地新写的、尚未推送到远程的提交“拔出来”临时存放到一个安全的地方。将本地分支的起点更新“变基”到远程origin/master的最新提交上也就是把远程的新提交先拉下来排在前面。把刚才临时存放的本地提交一个一个重新“贴”在远程最新提交的后面。生成物不会产生额外的 Merge commit。你本地的提交虽然内容没变但由于基于的“底座”变了它们的 Commit ID哈希值实际上被重新计算并改变了。历史线索变成了一条完美的、干净的单向直线。从历史记录上看就好像你是在远程最新代码的基础上一口气一口气写完这些新提交一样。3. 直观对比表维度git pull(merge)git pull --rebase底层命令git fetchgit mergegit fetchgit rebase是否产生合并节点是会生成一个 Merge Commit否完全没有多余的合并节点分支历史形态复杂的树状网保留真实的分支分叉历史干净的单一直线历史提交哈希 (Hash ID)原有本地提交的 Hash 不变本地未推送到远程的提交Hash 会被重写处理冲突的体验一次性解决所有冲突然后生成合并提交如果有多个提交可能需要按提交顺序重复多次解决冲突4. 冲突解决时的本质区别遇到代码冲突时两者的应对方式也大相径庭使用git pull时你只需要在本地把冲突文件改好执行git add .和git commit。只用解决一次冲突合并就完成了。使用git pull --rebase时因为它是把你的提交“一个一个往后贴”如果你的本地有 3 个 commit它们都和远程修改了同一行Git 贴第 1 个 commit报错冲突。你修改完后需要执行git add .然后执行git rebase --continue。Git 继续贴第 2 个 commit可能再次报错冲突你需要重复上面的步骤直到全部贴完。(如果觉得太麻烦或改乱了随时可以通过git rebase --abort彻底回滚到拉取前的状态) 团队开发建议什么时候用--rebase在本地特性分支上拉取主干更新例如在自己的 feature 分支拉取公共master或者在向远程推送前。这样可以保证主分支Mainline的历史是一条直线非常利于代码回滚Revert和 Code Review。什么时候不用--rebase绝对不要对已经推送到公共远程仓库的提交进行 rebase重写已经公开的提交历史会导致其他协同开发人员的本地仓库发生严重错乱。