ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TIL:用三行 Git 命令把最新提交转移到新分支(Move The Latest Commit To A New Branch)

TIL:用三行 Git 命令把最新提交转移到新分支(Move The Latest Commit To A New Branch) 文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载在基于master分支开发时偶尔会犯一个经典错误把本应放在独立 feature 分支上的提交直接提交到了master上。本指南基于 TILToday I Learned仓库中的 Move The Latest Commit To A New Branch 笔记介绍一种不重做提交、不动代码内容仅靠三条命令就把最新提交整体搬到新分支的 Git 技巧。读完你将掌握这套操作的完整命令、逐条原理、边界条件与回退保险手段可直接复用于任意分支场景。典型场景提交落在了错误的分支上你正在master分支上工作写完功能后直接git commit提交完成才意识到这个改动应该属于一个独立的功能分支而不是直接落在主分支上。此时master的HEAD就是这个放错了位置的提交。最常见的直觉解法是撤销再重来用git reset撤销这次提交保留工作区内容检出并创建新分支在新分支上重新git commit。这套流程的问题在于提交本身已经是一个不可变的历史对象撤销后需要重新生成一遍提交信息、重新关联父提交属于重复劳动而且一旦reset后又想反悔就得借助reflog找回增加了出错面。更好的方式三条命令完成转移与其撤销提交再重新提交不如反过来利用 Git 分支的本质——分支只是指向某个提交的可移动指针。先让新分支指向这个多余的提交再把master移回去提交内容原封不动一步都不用重做$ git checkout -b my-new-branch $ git checkout - $ git reset --hard HEAD~逐条拆解这三条命令步骤命令作用1git checkout -b my-new-branch从当前master的HEAD即最新提交处创建并切换到新分支my-new-branch此时这个放错位置的提交成为新分支的头2git checkout -切回上一个分支即master-是git checkout {-1}的简写表示上一个停留过的分支3git reset --hard HEAD~将master分支指针回退一个提交移除那个最新提交由于该提交已由my-new-branch持有历史内容并未丢失执行完毕后my-new-branch拥有完整的新功能提交master回到该提交之前的干净状态且无需重新编写提交信息、无需重新暂存文件。关于git checkout -的细节可参考同仓库笔记 Checkout Previous Branch其中明确指出git checkout -等价于git checkout {-1}即上一个分支这个技巧也常被用来在master与 feature 分支之间快速来回切换。为什么这比撤销 重新提交更好原笔记给出的理由非常直接它更好地利用了分支机制避免了重新做一个已经做过的提交This makes better use of branches and avoids the need to redo a commit that has already been made.。从 Git 的对象模型看一次提交commit是内容、作者、时间戳与父提交的哈希组合。撤销再重提交会生成一个全新的提交对象而本方案中的提交对象从头到尾只有一个只是被不同分支指针在不同时刻引用。所有历史、签名、时间信息都保持原样这正是移动而非重做的本质区别。使用前提与注意事项确保工作区干净再执行reset --hard第三步的git reset --hard HEAD~会同时移动分支指针、重置暂存区并丢弃工作区中未被跟踪的改动。同仓库的 Resetting A Reset 笔记提醒这类硬重置对已跟踪文件的改动是无法挽回的。因此执行前应确认没有未提交的修改例如先运行git status检查。若存在未提交改动可先用git stash暂存参考 Stash Everything再执行上述流程。适用于任意分支不限于master原笔记特别注明示例基于master但该流程适用于任何分支。只要第一步的git checkout -b发生在正确的分支上、第二步的git checkout -能正确回到原分支即可。reset --hard之后仍有后悔药如果执行后反悔比如发现my-new-branch不该存在不必慌张。Git 的 reflog 会记录HEAD的每次移动历史Resetting A Reset 演示了用git reflog找到HEAD{1}重置前的位置并通过git reset HEAD{1}恢复Accessing A Lost Commit 说明即使丢失了提交也能通过git reflog找到其 SHA再用git show、git cherry-pick或git rebase找回。也就是说这套移动提交的操作本身是可逆的安全边际比删除提交大得多。相关变体与延伸技巧用git switch替代git checkout -bGit 2.23 起引入了职责更单一的git switch。参考 Create A New Branch With Git Switch创建并切换分支可写成$ git switch -c my-new-branch-c等价于先git branch new-branch再git switch new-branch。若你的 Git 版本支持完全可以把第一步替换为git switch -c my-new-branch语义更清晰。不想硬重置时用交互式 rebase 丢弃提交如果你对git reset --hard心存顾虑且当前分支的工作目录与暂存区都是干净的可以改用交互式 rebase 显式 drop 掉提交。参考 Dropping Commits With Git Rebase$ git rebase -i master在打开的编辑器中把要移除的提交前的pick改为ddrop保存退出即可。这种方式的好处是零歧义——明确知道哪些提交被移除。误建分支的处理改基点与改名若新分支的基点选错了例如本应从qa分支出发却基于develop可用git checkout -B强制重置分支基点但注意这会清空该分支上已提交的内容参考 Change The Start Point Of A Branch 中的警告若只是分支名不满意可直接git branch -m new-name重命名参考 Renaming A Branch。只想撤回某个文件的改动如果误提交只涉及个别文件而非整条分支无需移动提交用git restore --sourceref file从指定引用恢复文件即可参考 Undo Latest Changes Committed To Specific File。小结把最新提交转移到新分支的核心是新分支先接管提交原分支再回退指针。它避免了撤销与重做的双重开销保留了提交对象的完整性且每一步都有reflog作为安全网。配合git switch、交互式 rebase 与 restore 等现代命令日常误操作几乎都能在不动代码内容的前提下被优雅地修正。如果你希望继续深入这一主题仓库中还收录了更多 Git 分支与历史修复笔记可在 git 目录 中按需查阅例如 Checkout Previous Branch、Resetting A Reset 与 Accessing A Lost Commit。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐30 seconds of code如何将误提交的 commit 从 master 分支移动到新分支30 seconds of code如何将误提交的 commit 从 master 分支移动到新分支 在日常开发中你可能会一时疏忽把本应提交到功能分支的改教程文档如何把微信聊天记录导出成 HTML、Word、CSV 永久保存WeChatMsg 完整指南如何把微信聊天记录导出成 HTML、Word、CSV 永久保存WeChatMsg 完整指南 你的微信聊天记录都躺在 PC 客户端的本地数据库里换电脑、重装系大模型本地部署推理引擎模型量化嵌入式CloudNativePG WAL 归档机制深度解析插件化架构、archive_timeout 与对象存储集成实战CloudNativePG WAL 归档机制深度解析插件化架构、archive_timeout 与对象存储集成实战 CloudNativePG 作为 Kube文档教程知识库上一篇ElasticJob监控数据导出完全指南自定义报表与可视化分析终极教程下一篇单调栈终极指南如何快速解决Next Greater Element类问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表