Git检出

git checkout命令的实质就是修改HEAD本身的指向,该命令不会影响分支"游标"(如master)

HEAD的重置即检出

HEAD可以理解为"头指针",是当前工作区的基础版本,当执行提交时,HEAD指向的提交将作为新提交的父提交。
git branch -v
结果

  • *master b2a5a95 does master follow this new commit
    然后执行如下命令
    git checkout b2a5a95 ^
    就会处于"分离头指针"状态。该状态是指HEAD头指针指向的是一个具体的提交ID,而不是一个引用(分支)
    然后创建一个文件 touch detached-commit.txt,加到暂存区git add detached-commit.txt,再然后git commit -m "commit in detached HEAD mode",此时头指针指向了新的提交,然后再git checkout master回到master分支,HEAD重新指向了master分支,而不是出于"分离头模式",切换之后,之前新建了本地文件detached-commit.txt不见了,刚刚提交的日志也不见了。但是使用git show [刚刚提交的ID]命令能在版本库中看到这个提交,但由于这个提交没有被任何分支跟踪到,因此并不能保证这个提交会永久的存在。实际上当reflog中含有该提交的日志过期后,这个提交随时会从版本库中彻底清除掉
挽救分离头指针

在"分离头指针"模式下进行的提交除了使用提交的ID来访问之外,不能通过master分支或者其他分支访问到,如果这个提交时master分支所需要的,那么该如何处理呢?如果使用git reset命令把master分支重置到该测试提交的分支上,那么会丢掉master指向的当前的提交。使用git merge合并操作可以两者兼顾。

深入了解git checkout命令
  • 用法一 git checkout [-q] [] [--]
  • 用法二 git checkout []
  • 用法三 git checkout [-m] [[-b|--orphan] ] []
    第一种用法的是可选项,如果省略则相当于从暂存区检出,这和git reset不一样,git reset默认的是HEAD,而git checkout默认的是暂存区,因此重置一般用于重置暂存区(除非使用了--hard参数,否则不会重置工作区),而检出命令主要是覆盖工作区(如果参数不省略,也会替换暂存区中相关的文件)
    第一种用法不会改变HEAD的头指针,主要用于指定版本的文件覆盖工作区中对应的文件。如果省略了,则会用暂存区的文件覆盖工作区的文件,否则用指定提交中的文件覆盖暂存区和工作区中对应的文件
    第二种用法最主要的作用是切换分支。如果省略则相当于对工作区进行状态检查
    第三种用法主要是创建和切换分支(),新的分支从指定的提交开始创建。
    下图展示了检出命令和版本库之间的关系
    检出命令和版本库

    示例用法:
  • git checkout branch 检出到branch分支,会执行1,2,3步骤。更新HEAD指向以指向branch分支以及用branch指向的树更新暂存区和工作区
  • git checkout 汇总显示工作区,暂存区与HEAD的差异
  • git checkout HEAD 效果同上
    -git checkout -- filename 用暂存区中filename文件来覆盖工作区的filename文件。相当于取消自上次执行git add filename命令以来工作区的本地修改
  • git checkout branch -- filename 维护HEAD的指向不变,用branch所指向的提交的filename文件替换掉工作区和暂存区中相应的文件
  • git checkout -- . 或者 git checkout .这条命令很危险,会取消所有本地的修改(相当于暂存区)。相当于用暂存区的所有文件直接覆盖本地文件。不给用户任何确认的机会

你可能感兴趣的:(Git检出)