Git 检出

本贴最后更新于 2300 天前,其中的信息可能已经事过境迁

Git 检出

标签(空格分隔): Git 学习笔记


仔细想想 git reset 命令的作用就是修改引用,如 git reset HEAD^ 就是将 master 的引用改变。可以发现,在 git reset HEAD^ 中并没有设置任何参数对所要重置的分支名进行设置,例如:我们并没有 git reset master HEAD^ 这样;这是因为重置命令实际上所针对的是 头指针 。之所以重置命令没有改变头指针 HEAD 的内容,是因为 HEAD 指向了一个引用 refs/heads/master ,所以重置命令体现为 分支上游标 的变更,HEAD 本身一直指向的是 refs/heads/master,并没有在重置时改变。
这个地方比较绕,我的理解是 HEAD 指向 refs/heads/master,而 refs/heads/master 里又记录这个分支的提交链,使用 reset 命令会改变 refs/heads/master 这个文件里记录的提交 ID,并不会改变 HEAD 指向 refs/heads/master 这个事实,但是想改变 HEAD 指向的内容(也就是想让 HEAD 指向其它分支),就要使用 git checkout 这个命令,这样就保证了 reset 命令永远会作用在当前这个分支上。

1 HEAD 的重置既检出

HEAD 可以理解为 头指针 ,是当前工作区的 基础版本

1.1 分离头指针

分离头指针 状态是指 HEAD 头指针指向了一个具体的提交 ID,而不是一个引用(一个分支)。处于分离头指针状态下时,我们可以检查、测试、提交,而不会影响任何分支。但是通过另外一个 checkout 检出指令会丢弃在此状态下的修改和提交。若想保留,使用 -b 参数调用 checkout 检出指令以创建新的跟踪分支。例如:git checkout -b newbranch_name

[root@izwz9f5nsv33jsmjcx0qw1z demo]# cat .git/HEAD
ref: refs/heads/master
[root@izwz9f5nsv33jsmjcx0qw1z demo]# git branch -v
* master 3f39502 commit
[root@izwz9f5nsv33jsmjcx0qw1z demo]# git checkout '3f39502^'
Note: checking out '3f39502^'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at ee76d8a... inset qwe
[root@izwz9f5nsv33jsmjcx0qw1z demo]# cat .git/HEAD 
ee76d8a1bd776d7042c7054e5abf180b371550cf
[root@izwz9f5nsv33jsmjcx0qw1z demo]# git branch -v
* (detached from ee76d8a) ee76d8a inset qwe
  master                  3f39502 commit
[root@izwz9f5nsv33jsmjcx0qw1z demo]# 

通过查看 reflog 也可以看到当针对提价执行了检出指令时,HEAD 头指针被改变。如下:

[root@izwz9f5nsv33jsmjcx0qw1z demo]# git reflog -1
ee76d8a HEAD@{0}: checkout: moving from master to 3f39502^
[root@izwz9f5nsv33jsmjcx0qw1z demo]# git rev-parse HEAD master
ee76d8a1bd776d7042c7054e5abf180b371550cf
3f39502c130889248d8794f42a1cb784a785d402

##2 挽救分离头指针
分离头指针 模式下进行的提交只能通过提交 ID 进行访问,虽然这个提交确实存在于版本库中,但是这个提交没有被任何分支跟踪到。因此当 reflog 中含有该提交的日志过期后,这个提交随时会从版本库中彻底清除。
若想保留 分离头指针 状态下的提交到 master 分支,可以使用 git merge 命令进行合并,操作如下:

  • 将分离头指针状态的下的修改进行提交,并记录提交 ID
  • 切换到 master 分支,执行 git merge commitid,这里的 commitid 为分离头指针状态下的提交 ID

合并后查看最新的提交,会发现这个提交有两个父提交,这就是合并的奥秘。如下:

[root@izwz9f5nsv33jsmjcx0qw1z demo]# git cat-file -p HEAD
tree 3c4aef196da70c04a2f1dcca3f07bd2432d3c884
parent 3f39502c130889248d8794f42a1cb784a785d402
parent 7b421dbc5d925a91e3d20d201cf7351addcc1f9f
author shiweichn <shiweichn@163.com> 1505356200 +0800
committer shiweichn <shiweichn@163.com> 1505356200 +0800

Merge commit '7b421db'

提交线也能体现这一点,如:

[root@izwz9f5nsv33jsmjcx0qw1z demo]# git log --graph --pretty=oneline 
*   5a6b4a4493b798c090aa7b314ab3359e4562b2b1 Merge commit '7b421db'
|\  
| * 7b421dbc5d925a91e3d20d201cf7351addcc1f9f new commit
* | 3f39502c130889248d8794f42a1cb784a785d402 commit
|/  
* ee76d8a1bd776d7042c7054e5abf180b371550cf inset qwe
* f325ad0df30feeaea3804ec7f3b895688dabd37d Initial demo666

3 深入了解 git checkout

git checkout 检出命令是 Git 常用的命令之一,但也很危险,因为会重写工作区。用法如下:

git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] [--detach] [<commit>]
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
git checkout [-p|--patch] [<tree-ish>] [--] [<paths>...]

QQ 截图 20170914114106.png-250.7kB

  • git checkout branch
    检出 branch 分支,执行了上图中的三个步骤,即改变 HEAD 的指向,替换了暂存区,替换工作区。

  • git checkoutgit checkout HEAD
    汇总显示工作区、暂存区与 HEAD 的差异

  • git checkout -- filename
    用暂存区的文件替换工作区的文件,慎用。一旦替换,无法找回。

  • git checkout branch --filename
    用 branch 所指向提交中的文件替换当前分支暂存区和工作区中的文件。

  • git checkout .
    用暂存区目录树覆盖工作区,工作区所有修改都会彻底丢失。慎用。

  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖 • 2 关注
  • Simon
    20 引用 • 10 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...