06.Git从放弃到入门: 命令checkout图解

10,005 阅读5分钟

前言

git checkout 命令用来切换分支,或者检出内容到工作目录。本文通过图文结合方式讲解其功能和工作原理。

本系列更多文章详见专栏 📚 Git从放弃到入门

项目初始化

接下来结合上篇分支里面的知识点,通过图解的方式来说明命令调用后发生了什么操作!

首先初始化一个项目,用于后续示例演示。创建两个分支一个 masterdev 。项目目录下有两个文件file.txtReadme.md

image.png

项目提交记录如下 👇。

image.png

检出内容

命令从历史提交(或者暂存区域)中检出内容到工作目录,该命令不会改变 HEAD 头指针,也就是当前分支不会发生变化。

未指定提交

使用 git checkout -- <file> 检出内容到工作目录 。-- 可以省略(git checkout <file>), 主要用于防止文件路径和分支名称混淆(git checkout <file>git checkout <branch> 命令结构相同) 。

命令未指定提交,默认检出当前暂存区的文件覆盖工作目录的文件。

在初始项目中,变更file.txt文件内容 v5v6 by checkout。然后使用git checkout -- file.txt命令使用暂存区域的文件内容进行覆盖。

image.png

命令流程如下 👇。

image.png

若项目文件存在已暂存状态,调用命令时还是使用暂存区域的文件内容进行覆盖。只是当前的暂存区域中文件尚未提交,没有出现在提交快照中(下次提交的快照中)。

接下来通过实例进行验证。在初始项目中,变更file.txt文件内容 v5v6 by staged;然后使用git add file.txt暂存更改;接下来继续更改file.txt内容为todo

使用git checkout -- file.txt命令后本地文件内容重置暂存后的 v6 by staged,而不最后提交的v5

image.png

命令流程如下 👇。

image.png

指定提交

使用 git checkout <commit> <file> 命令从指定的历史提交检出文件覆盖暂存区域和工作目录中对应的文件。

使用 git checkout HEAD~2 file.txt 命令会将当前提交节点 HEAD~2(当前提交节点的父节点的父节点,节点8e47817)中的 file.txt 更新暂存区域(索引)并且覆盖工作目录中对应的文件。当前分支不会发生变化,不会改变 HEAD 头指针。

image.png

HEAD 当前提交节点
HEAD~ 当前提交节点的父节点
HEAD~2 当前提交节点的父节点的父节点
HEAD~N 当前提交节点的父节点......的父节点

查看命令运行情况,当执行git checkout HEAD~2 file.txt 命令后,file.txt文件内容更新为 v4,暂存区域file.txt更新。 HEAD 头指针未改变还是指向master分支。

image.png

命令流程如下 👇。

image.png

切换分支

运行 git checkout <branch>命令,移动HEAD标识指向指定分支,也就是“切换”至该分支了。

暂存区域和工作目录中的内容和 HEAD 对应的提交节点一致。如果是切换到一个较旧的分支,工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。

image.png

首先查看下项目的提交记录和文件状态,此时HEAD指向master分支,目录是干净的不存在已修改、已暂存文件。

image.png

运行 git checkout dev命令切换分支后,再次查看提交记录和文件状态,此时HEAD已指向dev分支,目录是干净的。

image.png

新的提交节点(7632a63)中的所有文件都会被复制到暂存区域和工作目录中;只存在于老的提交节点(7416512)中的文件会被删除,所以文件Readme.md被删除,当前目录只有 file.txt 文件(文件内容为v3)。

image.png

查看暂存区域(索引)

使用 git ls-files 命令查看暂存区域(索引)内容。暂存区域(索引)在技术上并非树结构,它其实是以扁平的清单实现的。

$ git ls-files -s

此时暂存区域(索引)只有文件file.txt,文件Readme.md在更新中被移除了。

image.png

简单合并

checkout 对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢。 它会在工作目录中先试着简单合并一下,这样所有还未修改过的文件都会被更新。若是无法合并,将禁止切换分支。

在初始项目中,先修改 file.txt 文件内容,然后尝试切换分支,显示覆盖操作存在冲突,切换命令被终止。

image.png

忽略已修改或已暂存文件

上文中可知对于只存在于老的提交节点中的文件会被删除。若是存在已修改或已暂存的文件会被忽略,不受影响,状态保留。

在初始项目中,新增文件 lib\simplegit.py

print('hi,git!') 

使用 git add lib/simplegit.py 添加至暂存区域,然后继续修改 lib\simplegit.py 内容。

print('hello,git!') 

此时工作目录状态如下 👇。

image.png

此时暂存区域(索引)文件如下 👇。

image.png

然后运行 git checkout dev命令切换分支后,lib/simplegit.py文件仍保留。

image.png

查看目录状态和文件内容,lib/simplegit.py文件的已修改或已暂存内容都被保留。

image.png

查看索引内容,lib/simplegit.py的已暂存状态也被保留更新。

image.png

命令流程如下 👇。

image.png

📚参考&关联阅读

"重置揭密",Pro Git
"git checkout",Pro Git
"git checkout",Pro Git

关注专栏

如果本文对您有所帮助请关注➕、 点赞👍、 收藏⭐!您的认可就是对我的最大支持!

此文章已收录到专栏中 👇,可以直接关注。