是,原分支的提交仍在;git checkout -b new-branch仅创建指向相同commit的新指针,不移动原分支HEAD,所有未推送提交仍保留在原分支上。

git checkout -b 创建新分支后,原分支的提交还在吗
还在。用 git checkout -b new-branch 从当前分支创建新分支时,只是新建了一个指向相同 commit 的指针,原分支的 HEAD 并未移动,所有已提交(git commit 过)但未推送(git push)的提交仍然保留在原分支上——这不是你想要的结果。
真正要的是:把「已提交但尚未推送到远程」的那些 commit,从当前分支“摘下来”,挪到一个新分支上,同时让原分支回退到推送过的最新状态(即撤销这些本地提交)。
- 核心操作不是
git checkout -b,而是git branch+git reset --hard - 必须确认当前分支最后一次推送的 commit 是哪个,常用
git log origin/main或git log origin/main..HEAD查看本地独有的提交 - 如果远程分支名不是
main,请替换成实际名,比如origin/master
如何安全地把未推送提交“剪切”到新分支
本质是两步:先用 git branch new-branch 把当前 HEAD 记为新分支起点,再用 git reset --hard origin/main 把原分支强制回退到远程对应位置。
示例(假设当前在 main 分支,远程跟踪分支是 origin/main):
git branch feature/unpushed git reset --hard origin/main
执行后:
– feature/unpushed 指向原来 main 的 HEAD(含所有未推送提交)
– main 回退到和 origin/main 完全一致的状态
– 工作区和暂存区保持干净(因为 reset --hard 会同步重置它们)
- 务必先运行
git status和git log --oneline origin/main..HEAD确认哪些提交将被“移走” - 如果本地有未提交的改动(working directory changes),
reset --hard会直接丢弃,需先git stash或提交 -
origin/main必须存在且已更新(git fetch最好刚执行过),否则可能回退过度
为什么不用 git cherry-pick 或 git rebase
这两种方式是“复制”而非“移动”:cherry-pick 会生成新 commit(SHA 改变),rebase 会重写历史(即使只针对未推送提交,也可能引发协作混乱)。而 git branch + reset 是纯指针操作,不改变任何 commit 内容,效率高、可逆性强。
-
git cherry-pick A B C后,原分支仍保留 A/B/C,只是多出三份副本 -
git rebase -i origin/main虽能交互式筛选,但会重写所有选中 commit 的 hash,对后续协作不利 - 只要没
git push --force,git branch创建的分支完全本地,零风险
切换过去后怎么推送到远程
新分支默认不在远程,需要显式推送并设置上游:
git checkout feature/unpushed git push -u origin feature/unpushed
注意:
– -u(即 --set-upstream)让后续 git push 和 git pull 可以省略分支名
– 如果远程仓库拒绝(比如权限不足或保护分支限制),错误信息通常是 ! [remote rejected],此时需联系管理员或换分支名
– 推送成功后,原分支(如 main)已“干净”,可立即拉取最新变更继续开发
容易忽略的是:如果你之前在原分支上做过 git add 但没 commit,这些暂存内容不会被带走——git branch 只复制 commit 历史,不复制暂存区或工作区状态。


















