三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

15-checkout 的本质

15-checkout 的本质

在前面的branch的部分介绍过checkout可以用来切换branch

git checkout branch2

不过实质上,checkout并不止可以切换branchcheckout本质功能其实是:签出(checkout)指定的commit

git checkout branch名的本质,其实是让HEAD指向对应的branch,然后签出这个branch对应commit的工作目录。同样的,checkout的目标也可以不是branch,而是直接指向某个commit

git checkout HEAD^^
git checkout master~5
git checkout 78a4bc
git checkout 78a4bc^

这些都是可以的。

另外,如果你留心的话可能会发现,在git status的提示信息中,Git 会告诉你可以用checkout -- 文件名的格式,通过「签出」的方式来撤销(丢弃)指定文件的修改:

切换分支

  1. 切换到已有分支‌:git checkout <分支名>就能跳到目标分支,工作区文件会自动更新成该分支的内容 。
  2. 创建并切换新分支‌:git checkout -b <新分支名>一键创建新分支并切过去,相当于先建分支再切换两步合为一步 。
  3. 切换到远程分支‌:git checkout -t origin/<分支名>能从远程仓库检出分支并在本地创建跟踪分支 。
  4. 进入分离头指针状态‌:git checkout <commit-SHA>会进入detached HEAD状态,适合查看历史代码或调试旧版本,但在此状态下提交的内容不会关联到任何分支 。‌‌‌

恢复文件版本

  1. 丢弃未提交的修改‌:git checkout --<文件名>把文件恢复到最近一次提交或暂存的状态,本地未提交的改动会永久丢失 。
  2. 从其他分支恢复文件‌:git checkout <分支名> --<文件名>把指定分支上的某个文件复制到当前分支,无需合并整个分支 。
  3. 恢复已删除文件‌:如果文件被误删但未提交,用git checkout HEAD --<文件名>能从最后一次提交中恢复 。
  4. 交互式恢复部分代码‌:加上-p参数如git checkout -p --<文件名>可以逐块选择要恢复的代码,适合只想撤销部分改动的场景 。‌‌‌

需要注意的地方

  1. 未提交修改会阻止切换‌:如果工作区有与目标分支冲突的未提交修改,Git 会阻止切换,建议先用git stash暂存或提交后再切换 。
  2. 强制切换会丢数据‌:使用-f参数如git checkout -f <分支名>会强制切换并丢弃所有未提交修改,操作前务必确认 。
  3. 新命令更清晰‌:Git 2.23 版本后引入了git switch专门切换分支、git restore专门恢复文件,语义更明确,但checkout仍被广泛使用 。
  4. 文件名与分支名冲突‌:如果有个文件名叫hello.c同时也有个分支叫hello.c,Git 会优先当作分支处理,此时需用git checkout -- hello.c明确指定是文件 。‌‌‌

checkout 和 reset 的不同

checkoutreset都可以切换HEAD的位置,它们除了有许多细节的差异外,最大的区别在于:reset在移动HEAD时会带着它所指向的branch一起移动,而checkout不会。当你用checkout指向其他地方的时候,HEAD和它所指向的branch就自动脱离了。

事实上,checkout有一个专门用来只让HEADbranch脱离而不移动HEAD的用法:

git checkout --detach

执行这行代码,Git 就会把HEADbranch脱离,直接指向当前commit

小结

checkout的本质是签出指定的commit,所以你不止可以切换branch,也可以直接指定commit的 SHA-1 作为参数,来把HEAD移动到指定的commit

← 返回列表