>[success] # GIT 分支
1. `HEAD `文件是一个指针,其有一个特性就是总会指向当前分支的最新的一个 `commit `对象

2. 查看分支存储`cat .git/HEAD`

`cat .git/refs/heads/master` 查看当前master 的最新的`commit` 类型文件

* 日志`git log --graph`

* 让分支出现不同步,此时使用`git checkout testing`创建一个 `testing `分支,并修改文件在 `testing` 分支提交到本地仓库,切换回分支`master `( 可以发现此时`HEAD` 在`master`),但此时 `testing` 分支是领先的

接着做操作在 `master` 分支修改提交代码到本地仓库,执行`git log --all --graph --oneline`
* 可以发现从`c4f4a4a` 节点开始形成了两个走向

* 用图形表示(此图对应commit 信息并非当前案例)

>[danger] ##### 总结
当前`commit`在哪里,`HEAD`就在哪里,这是一个永远自动指向当前`commit`的引用,所以你永远可以用`HEAD`来操作当前`commit`
*****
`HEAD`是 Git 中一个独特的引用,它是唯一的。而除了`HEAD`之外,Git 还有一种引用,叫做`branch`(分支)。`HEAD`除了可以指向`commit`,还可以指向一个`branch`,当它指向某个`branch`的时候,会通过这个`branch`来间接地指向某个`commit`;另外,当`HEAD`在提交时自动向前移动的时候,它会像一个拖钩一样带着它所指向的`branch`一起移动

* `HEAD `-> `master`分支->`commit`

* 当创建`commit `时候 `HEAD`会带着`master`一起移动到最新的`commit`

>[danger] ##### master 分支
1. `Git `的 `master `分支并不是**一个特殊分支**,只是`Git `的默认分支名字是 `master`
2. 新创建的 repository(仓库)是没有任何`commit`的。但在它创建第一个`commit`时,会把`master`指向它,并把`HEAD`指向`master`
3. 当有人使用`git clone`时,除了从远程仓库把`.git`这个仓库目录下载到工作目录中,还会`checkout`(签出)`master`(`checkout`的意思就是把某个`commit`作为当前`commit`,把`HEAD`移动过去,并把工作目录的文件内容替换成这个`commit`所对应的内容)。可以理解成**远程仓库如果有多个默认分支,往往在第一次clon 下来代码,git 会为了确定当前 HEAD 往往默认指向 master 也就是间接指向master 的最新commit**

>[danger] ##### 切换分支时候

>[info] ## 分支指令
1. `git branch xxx` -- 创建一个分支,例如创建一个`testing `分支 `git branch testing `

2. `git checkout xxx` -- 切换分支`HEAD`就会指向新建的`branch`

创建分支后自动切换到创建的分支`git checkout -b xxx`
3. `git branch -d xxx` -- 删除分支
* `HEAD`指向的`branch`不能删除。如果要删除`HEAD`指向的`branch`,需要先用`checkout`把`HEAD`指向其他地方
* 由于 Git 中的`branch`只是一个引用,所以删除`branch`的操作也只会删掉这个引用,并不会删除任何的`commit`。如果没有任何一个`branch`可以回溯到这条`commit`,那么在一定时间后,它会被 Git 的回收机制删除掉

* 删除分支

* 但依旧可以在 `objects `文件中找到

* 如果分支一次都没有进行合并要删除的话把`-d`改成`-D`,小写换成大写,就能删除了
4. `git branch` -- 查看当前所有的分支
5. `git branch –v` -- 同时查看最后一次提交
6. `git branch --merged` -- 查看所有合并到当前分支的分支
7. `git branch --no-merged` -- 查看所有没有合并到当前分支的分支
8. `git merge xxx` -- 分支合并
>[danger] ##### 分支合并
1. 合并分支指令 `git merge xxx` ,例如将`testing `分支合并到 `master` 分支,需要先将分支切换到 `master` 分支 执行`git merge testing `
* 如图 testing 分支合并到了master 分支上,此时产生的新的 `commit` 节点会有两个`parent` 指向



2. `pull`的实际操作其实是把远端仓库的内容用`fetch`取下来之后,用`merge`来合并
>[danger] ##### HEAD 领先于目标 commit
如果`merge`时的目标`commit`和`HEAD`处的`commit`并不存在分叉,而是`HEAD`领先于目标`commit`,`merge`就没必要再创建一个新的`commit`来进行合并操作,因为并没有什么需要合并的。在这种情况下, Git 什么也不会做,`merge`是一个空操作

>[danger] ##### HEAD 落后于 目标 commit——fast-forward
如果`HEAD`和目标`commit`依然是不存在分叉,但`HEAD`不是领先于目标`commit`,而是落后于目标`commit`

那么 Git 会直接把`HEAD`(以及它所指向的`branch`,如果有的话)移动到目标`commit`
