这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
Git学习|青训营笔记
首先了解几个概念 HEAD,main以及branch
在查看git log 后
commit后面括号里的(HEAD -> main, origin/main, origin/HEAD),均是指向commit的引用,黄色字符串为每个commit的唯一SHA-1校验和,可以用校验和来指代某个commit,但这样表达过于繁琐,因此Git 提供了「引用」的机制:使用固定的字符串作为引用,指向某个 commit,作为操作 commit 时的快捷方式。
HEAD:当前commit的引用
HEAD 是引用中最特殊的一个:它是指向当前 commit 的引用。即当前工作目录所对应的 commit。
每次当有新的 commit 的时候,工作目录自动与最新的 commit 对应;而与此同时,HEAD 也会转而指向最新的 commit。
总之,当前 commit 在哪里,HEAD 就在哪里,这是一个永远自动指向当前 commit 的引用,所以永远可以用 HEAD 来操作当前 commit。
branch
branch是Git中另一类引用。
HEAD 除了可以指向 commit,还可以指向一个 branch,当它指向某个 branch 的时候,会通过这个 branch 来间接地指向某个 commit;另外,当 HEAD 在提交时自动向前移动的时候,它会像一个拖钩一样带着它所指向的 branch 一起移动。
例如上面的那张图里,HEAD -> master 中的 master 就是一个 branch 的名字,而它左边的箭头 -> 表示 HEAD 正指向它(当然,也会间接地指向它所指向的 commit)。
下图为再次git commit 后的git log
可以看到最新的
commit被创建后,HEAD指向main,main指向当前commit,而origin/main, origin/HEAD仍在原处
main:默认branch
main是特殊branch,是Git的默认branch,有以下特点:
- 新创建的 repository(仓库)是没有任何
commit的。但在它创建第一个commit时,会把master指向它,并把HEAD指向master。 - 当有人使用
git clone时,除了从远程仓库把.git这个仓库目录下载到工作目录中,还会checkout(签出)master(checkout的意思就是把某个commit作为当前commit,把HEAD移动过去,并把工作目录的文件内容替换成这个commit所对应的内容)。
大多数的开发团队会规定开发以 master 为核心,所有的分支都在一定程度上围绕着 master 来开发。这个在事实上构成了 master 和其它分支在地位上的一个额外的区别。
branch的创建,切换和删除
创建branch
想在某处创建branch,输入git branch 名称,例如在main上创建分支feature1
git branch feature1
切换branch
新建的 branch 并不会自动切换, HEAD 在这时依然是指向 master 的。需要用 checkout 来主动切换到新 branch 去:
git checkout feature1
然后 HEAD 就会指向新建的 branch 了:
除此之外,可以用 git checkout -b 名称 来把上面两步操作合并执行。
这行代码可以用指定的名称创建 branch 后,再直接切换过去。以 feature1 为例的话,就是:
git checkout -b feature1
在切换到新的 branch 后,再次 commit 时 HEAD 就会带着新的 branch 移动了
而这个时候,如果再切换到 master 去 commit,就会真正地出现分叉了:
git checkout master
... git
commit
删除branch
删除 branch 的方法非常简单:git branch -d 名称。例如要删除 feature1 这个 branch:
git branch -d feature1
删除时需要注意:
HEAD指向的branch不能删除。如果要删除HEAD指向的branch,需要先用checkout把HEAD指向其他地方。- 由于 Git 中的
branch只是一个引用,所以删除branch的操作也只会删掉这个引用,并不会删除任何的commit。(不过如果一个commit不在任何一个branch的「路径」上,或者换句话说,如果没有任何一个branch可以回溯到这条commit,那么在一定时间后,它会被 Git 的回收机制删除掉。) - 出于安全考虑,没有被合并到
master过的branch在删除时会失败(因为怕误删掉「未完成」的branch)
这种情况如果确认是要删除这个branch(例如某个未完成的功能被团队确认永久毙掉了,不再做了),可以把-d改成-D,小写换成大写,就能删除了。
「引用」的本质
所谓「引用」(reference),其实就是一个个的字符串。这个字符串可以是一个 commit 的 SHA-1 码(例:c08de9a4d8771144cd23986f9f76c4ed729e69b0),也可以是一个 branch(例:ref: refs/heads/feature3)。
Git 中的 HEAD 和每一个 branch 以及其他的引用,都是以文本文件的形式存储在本地仓库 .git 目录中,而 Git 在工作的时候,就是通过这些文本文件的内容来判断这些所谓的「引用」是指向谁的。
总结
-
HEAD是指向当前commit的引用,它具有唯一性,每个仓库中只有一个HEAD。在每次提交时它都会自动向前移动到最新的commit。 -
branch是一类引用。HEAD除了直接指向commit,也可以通过指向某个branch来间接指向commit。当HEAD指向一个branch时,commit发生时,HEAD会带着它所指向的branch一起移动。 -
master是 Git 中的默认branch,它和其它branch的区别在于:- 新建的仓库中的第一个
commit会被master自动指向; - 在
git clone时,会自动checkout出master。
- 新建的仓库中的第一个
-
branch的创建、切换和删除:- 创建
branch的方式是git branch 名称或git checkout -b 名称(创建后自动切换); - 切换的方式是
git checkout 名称; - 删除的方式是
git branch -d 名称。
- 创建