git pull 会让分支历史变叉,因为它默认执行 git fetch + git merge,每次远程有新提交就会生成 merge commit,形成分叉结构;多人频繁操作后,git log --graph 呈现混乱的“毛线团”状。

git pull 为什么会让分支历史变叉?
直接 git pull 是多数人默认操作,但它本质是 git fetch + git merge。一旦远程有新提交,git merge 就会生成一条 merge commit,把你的本地提交“包”进一个分叉结构里。多人反复这么干,git log --graph 看起来就像毛线团。
真正需要的是线性历史——让所有提交像流水一样排在远程分支最新提交之后。这靠 git rebase 实现,不是靠“拉取后合并”。
- 别再对共享分支(如
main、dev)用git pull - 改用
git fetch origin拉取元数据,再git rebase origin/main把本地提交“挪”到远程最新点后面 - 如果本地有未提交修改,先
git stash,rebase 完再git stash pop
多人同时推送到同一分支时被拒绝怎么办?
错误信息 Updates were rejected because the tip of your current branch is behind 不是失败,而是 Git 在保护你:别人已经推了新提交,你本地旧 HEAD 不能直接覆盖。
此时硬 git push --force 会丢别人代码,必须同步后再推。
- 先
git fetch origin获取远程最新状态 - 再
git rebase origin/<branch-name></branch-name>
(比如origin/dev),把你的提交重放上去 - 如果有冲突,解决后
git add . && git rebase --continue - 最后
git push即可——此时推送的是已 rebased 的干净线性提交
feature 分支合并进 main 前如何避免交叉污染?
很多人习惯在 feature 分支上直接 git merge main 来同步主线更新,但这会在 feature 分支里引入一条 merge commit,等你最终 PR 合并时,这条 merge 会被一起带进 main,污染主线历史。
正确做法是保持 feature 分支“纯净”,只包含你自己写的逻辑提交。
- 创建 feature 分支时确保基于最新
main:git checkout main && git pull origin main && git checkout -b feature/xxx - 开发中同步主线更新,用
git fetch origin && git rebase origin/main,而不是 merge - PR 被批准后,由 CI 或维护者用 squash merge 或 rebase merge 合入
main,不保留 feature 分支的原始 commit 图谱
本地分支删了但 git branch -a 还显示远程分支残留
执行过 git push origin --delete feature/old,但 git branch -a 仍看到 remotes/origin/feature/old,这不是 bug,是本地缓存没清理。
Git 不会自动同步远程分支删除动作到本地 refs,必须手动修剪。
- 运行
git fetch --prune origin(或简写git fetch -p origin) - 也可配置全局自动修剪:
git config --global fetch.prune true - 注意:该操作只删本地缓存的 remote-tracking 分支,不影响任何本地分支或远程仓库真实内容
rebase 当成“魔法命令”乱用——它重写 commit hash,所以绝不能对已推送过的公共分支执行 git push --force。只应在自己尚未推送的 feature 分支上安全使用。











