2026/2/17 15:47:25
网站建设
项目流程
网站建设与制,免费微网站哪个好用,榆林城乡建设规划官方网站,东莞响应式网站哪家强Git学习日志——为什么你的分支会莫名出现别的分支的提交
笔者之前做项目的时候#xff0c;曾经被CR道#xff1a;你的这次提交混入了之前的其他bug fix的提交了#xff0c;处理一下。当你在 Git 里看到「我没 merge、没 rebase#xff0c;为什么分支里却出现了别处的 comm…Git学习日志——为什么你的分支会莫名出现别的分支的提交笔者之前做项目的时候曾经被CR道你的这次提交混入了之前的其他bug fix的提交了处理一下。当你在 Git 里看到「我没 merge、没 rebase为什么分支里却出现了别处的 commit」时你并不孤单。这个问题既常见又容易修复 —— 关键是理解分支就是一个指针永远从当前的HEAD开始。TL;DR**新分支从当前HEAD创建如果 HEAD 本身包含了别的分支的提交新分支也会带上它们。**一个最简单的办法就是如果没有特殊要求永远从最新的基准线拉分支出来直观理解想象 Git 是家谱每个 commit 是“一个人”分支是“出生地点”。你在哪里出生HEAD你的整个家族链就是什么。如果你以为你在“爸爸main”那儿出生但实际上你在“叔叔dev”那儿开始——那当然会“带着叔叔的血统”。ASCII 图示示例A --- B --- C --- D (main) \ E --- F (dev) \ G --- H (feature) -- 从 dev 或 D 创建可能带 E/F/D常见原因为什么会出现别的 commit且你可能没察觉创建分支时 HEAD 在错误分支/commit最常见忘记git switch main直接git switch -c feature。你执行过git pull默认是 fetch merge把远端的 commit 合入了本地分支。你在某分支做了提交、amend 或 reset改变历史后又开分支历史改写导致“看起来是前面的提交”。本地 main 落后于 origin/main你从本地落后的 main 开分支。分支 fast-forward 或被别人合并到 main然后你从该分支再开分支。IDE/工具的自动操作auto stash / auto rebase / auto merge在背后帮你做了改写/合并。关键结论完全可以不触发显式merge/rebase也能把别处的 commit 带过来 —— 因为你站在包含它们的位置开了分支。如何复现在本地做实验理解会更深刻把下面脚本复制到临时目录运行或逐条执行每个场景都有注释。场景 A在错误分支上创建新分支最常见gitinit demo-mixcddemo-mixechoAfilegitadd.gitcommit -mAechoBfilegitcommit -amBgitbranch devgitswitch devechoCfilegitcommit -amC# dev 上有 C# 忘记切回 main直接创建 featuregitswitch -c featuregitlog --oneline --graph --decorate# 你会看到 C 出现在 feature 上场景 B本地 main 落后从落后版本开分支# 模拟远端和本地简化版# 在远程仓库里已有额外 commit这里直接在本地把 main 往前 reset 来模拟gitswitch mainechoXfilegitcommit -amX# 假设远端比本地多了 C、D现实中是别的协作产生的# 你没拉取就开分支gitswitch -c feature-from-old-main# 以后 pull/fetch 时你会发现远端的 C/D 跑进来并改变预期场景 Camend / reset 后开分支历史改写导致gitswitch -c branch1echoBfilegitcommit -amBgitcommit --amend -mB (amended)# 改写 branch1 历史gitswitch maingitswitch -c featuregitlog --oneline --graph# 可能看到被 amended 的提交出现在 feature修复方法按场景分选择最适合你的警告重要任何改写历史的操作reset --hard,rebase,push --force在共享分支上必须小心。改写别人可能基于的历史会引起冲突。已 push 的改动要在团队里协调后再强推。场景我想保留自己的提交把多出的其他提交去掉工具git rebase --onto最干净假设你当前分支feature历史如下你要把 F,G,H 接到 C 后面去掉 D、EA - B - C - D - E (main) \ F - G - H (feature)命令假设你知道正确基点C的 hash 或分支名gitswitch featuregitrebase --ontoCDfeature# 例如 git rebase --onto C D feature效果把 F/G/H“剪”下来接到 C 后面。场景分支很短想简单处理 —— 重新创建并 cherry-pickgitswitch maingitpull --ff-onlygitswitch -c feature-cleangitcherry-pickhash-of-your-commit-1gitcherry-pickhash-of-your-commit-2# 如果冲突按提示解决适合更改不多时用最保守。场景刚做了 merge但还没 push想撤销 merge# 回到 merge 之前的 commit确保你知道要回退到哪个gitreset --hardcommit-before-merge仅当未 push 到远端或确定没人依赖时使用。场景已经 push 到远端需要删除特定提交慎用使用git rebase -i base在本地把多余的 commitdrop掉。强推到远端通知团队gitpush --force-with-lease origin feature--force-with-lease比--force更安全它会在远端有人更新时拒绝强推。场景不知道基点或不确定先看历史gitlog --graph --oneline --decorate --allgitreflog# 查看最近 HEAD/checkout 的历史帮助找到正确点那怎么做就不会遇到这类麻烦呢把这 5 步写在贴纸上每次开分支都按顺序来# 推荐的 5 步严格开分支流程gitswitch maingitfetch --allgitpull --ff-onlygitstatus# 确认 On branch main working tree cleangitswitch -c feature/xxx额外规则强化在团队中统一约定feature 分支必须从最新的 main 创建CI 检查分支基点可选。避免在还没推到远端的分支上使用commit --amend,rebase -i或在改写历史前通知团队。已 push 的公共分支不要强制改写历史私人分支可以随意改写。快速备忘 Cheat-Sheet常用命令与用途检查历史图形化gitlog --graph --oneline --decorate --all找到最近 HEAD 操作gitreflog从正确基点把你的提交剪到新位置去掉中间的别的 commitgitrebase --ontonew-baseold-basebranch交互式清理提交drop / squash / reordergitrebase -ibase重新从正确基点 cherry-pick最保守gitswitch maingitpull --ff-onlygitswitch -c feature-cleangitcherry-pickcommit1commit2...撤销最近一次合并如果未 pushgitreset --hardcommit-before-merge强推仅在协调后gitpush --force-with-lease origin feature故障排查清单当你遇到“莫名 commit”时照着做先别慌别立刻push --force。git log --graph --oneline --decorate --all看是哪条线把那些 commit 带进来的。git reflog看最近你都做了哪些 checkout / reset / amend。确认是否有人在远端把某个分支合并到 maingit fetchgit log origin/main。根据你的目标保留你 commit / 重新建分支 / 回退 merge选择上面的修复方法。如果要改写远端历史先告知团队并使用--force-with-lease。