Git Branch

此篇介绍Git分支的一些操作,以及原理。

Begin

git branch

当本地无分支时。一键创建分支并切换。切换分支后,HEAD改变。

1
2
3
4
5
$ git-exercise git:(main) git checkout -b sami
Switched to a new branch 'sami'

$ git branch sami 创建分支
$ git checkout sami 切换分支

init

  1. 在main分支提交两次。文件分别master1.txt, master2.txt
  2. 在选中处,创建并切换分支sami。
  3. 之后在sami分支提交两次,文件为同一文件sami1.txt
1

理解上图。之所以一条线是因为自从checkout至sami,main无修改,sami基于main。在sami分支目前三个文件。而切换至main分支仍然是之前两个文件。通俗来讲,再切换至main做一次commit就会出现分叉了。

2

sourcetree中空心即为本地HEAD指向。上图切换至sami分支显然main修改的最新文件它不会有。

checkout 的意思就是把某个 commit 作为当前 commit,把 HEAD 移动过去,并把工作目录的文件内容替换成这个 commit 所对应的内容。

上图实际包含很多知识点。下面先介绍。

Git 提供了「引用」的机制:使用固定的字符串作为引用,指向某个 commit,作为操作 commit 时的快捷方式。

HEAD 是引用中最特殊的一个:它是指向当前 commit 的引用。所谓**当前 commit**这个概念很简单,它指的就是当前工作目录所对应的 commit

要想理解这一句。首先建立概念,对于Git来说,核心是commit s,工作目录的代码归根结底根据commit而变。

每次当有新的 commit 的时候,工作目录自动与最新的 commit 对应;而与此同时,HEAD 也会转而指向最新的 commit。事实上,当使用 checkoutreset 等指令手动指定改变当前 commit 的时候,HEAD 也会一起跟过去。

总之,当前 commit 在哪里,HEAD 就在哪里,这是一个永远自动指向当前 commit 的引用,所以你永远可以用 HEAD 来操作当前 commit

此时可以理解为什么切换分支后,文件会不同。归根结底:切换到main分支时,HEAD指向main最新commit。而切换到sami分支时,查看log,HEAD指向sami分支最新commit。

branch

HEAD 是 Git 中一个独特的引用,它是唯一的。而除了 HEAD 之外,Git 还有一种引用,叫做 branch(分支)。HEAD 除了可以指向 commit,还可以指向一个 branch,当它指向某个 branch 的时候,会通过这个 branch 来间接地指向某个 commit;另外,当 HEAD 在提交时自动向前移动的时候,它会像一个拖钩一样带着它所指向的 branch 一起移动。每当创建一个 commit,那么 HEAD 会带着 master 一起移动到最新的 commit

delete branch

不常用。

删除 branch 的方法非常简单:git branch -d 名称。例如要删除 feature1 这个 branch:

注意:1. HEAD 指向的 branch 不能删除。如果要删除 HEAD 指向的 branch,需要先用 checkoutHEAD 指向其他地方。2. 由于 Git 中的 branch 只是一个引用,所以删除 branch 的操作也只会删掉这个引用,并不会删除任何的 commit。(不过如果一个 commit 不在任何一个 branch 的「路径」上,那么在一定时间后,它会被 Git 的回收机制删除掉。)

1
2
3
$ git branch -d feature1
//出于安全考虑,没有被合并到 master 过的 branch 在删除时会失败,强制删除用如下:
$ git branch -D feature1

引用本质

所谓「引用」(reference),其实就是一个个的字符串。这个字符串可以是一个 commit 的 SHA-1 码(例:c08de9a4d8771144cd23986f9f76c4ed729e69b0),也可以是一个 branch(例:ref: refs/heads/feature3)。

Git 中的 HEAD 和每一个 branch 以及其他的引用,都是以文本文件的形式存储在本地仓库 .git 目录中,而 Git 在工作的时候,就是通过这些文本文件的内容来判断这些所谓的「引用」是指向谁的。

总结

  1. HEAD 是指向当前 commit 的引用,它具有唯一性,每个仓库中只有一个 HEAD。在每次提交时它都会自动向前移动到最新的 commit
  2. branch 是一类引用。HEAD 除了直接指向 commit,也可以通过指向某个 branch 来间接指向 commit。当 HEAD 指向一个 branch 时,commit 发生时,HEAD 会带着它所指向的 branch 一起移动。
  3. master是 Git 中的默认branch,它和其它branch的区别在于:
    1. 新建的仓库中的第一个 commit 会被 master 自动指向;
    2. git clone 时,会自动 checkoutmaster
  4. branch的创建、切换和删除:
    1. 创建 branch 的方式是 git branch 名称git checkout -b 名称(创建后自动切换);
    2. 切换的方式是 git checkout 名称
    3. 删除的方式是 git branch -d 名称

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!