05.Git从放弃到入门:分支(Branch)图解

1,564 阅读4分钟

0x00 前言

Git 的分支模型是它的 “必杀技特性” ,其能力强大而又独特,处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。为了更好的使用它,需要理解这一特性。

本文通过图文结合方式介绍分支(Branch)基础概念,为后续深入分析打好基础。

本系列更多文章详见专栏 📚 Git从放弃到入门

0x01 分支(Branch)简介

Git 的分支本质上是指向提交对象的可变指针。 Git 的默认分支名字是 master, master 分支会在每次提交时自动向前移动,指向最后那个提交对象。

Git 的 master 分支并不是一个特殊分支。每一个仓库都有 master 分支,是因为 git init 命令默认创建它。它跟其它分支完全没有区别。

Git 保存的数据不是文件的变化或者差异,而是一系列不同时刻的快照 (snapshot)。在进行提交操作时,Git 会保存一个提交对象(commit object)。 该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。

HEAD 指针

告知 Git 当前在哪一个分支上。 它是一个指针,指向当前所在的本地分支,也可将其视为当前分支的别名。

0x02 工作流程图解

git init 创建仓库

运行 git init 创建一个 Git 仓库。由于分支是指向提交的指针,此时仓库没有任何提交,所以master 分支尚未创建,其中的 HEAD 引用指向未创建的 master 分支。在提交内容之前不能使用分支。

image.png

此时仓库状态如下👇。

image.png

git commit 首次提交

运行 git commit,它会取得暂存区中的内容并将它保存为一个永久的快照, 然后创建一个指向该快照的提交对象,最后更新 master 来指向本次提交。此时master分支已创建。首次提交产生的提交对象没有父对象。

image.png

git commit 普通提交

运行 git commit,它会取得暂存区中的内容并将它保存为一个永久的快照,并把此时的节点设为父节点,然后把当前分支指向新的提交节点。下图中,当前分支是 master。在运行命令之前,master 指向 11c6b2a,提交后,master 指向新的节点 7632a63 并以 11c6b2a 作为父节点。

image.png

普通提交操作产生的提交对象有一个父对象(包含一个指向父对象的指针), 而由多个分支合并产生的提交对象有多个父对象。

使用 git log 命令查看每次提交的父提交的简写哈希值,使用 %p 选项。

$ git log --pretty=format:'%h --> %p| %ad | %s%d [%an]' --graph --date=short

可以看到首次提交记录没有父对象的信息,其他的提交记录都可以看到父对象的提交hash就是上次提交记录的hash。

image.png

git branch 创建分支

使用 git branch创建新分支仅仅创建一个新分支,并不会自动切换到新分支中去。

下面创建 dev 分支:

$ git branch dev

查看提交记录可以看到 dev 分支指向了最新的提交记录。

image.png

如果不加任何参数运行 git branch ,会得到当前所有分支的一个列表。master 分支前的 * 字符:它代表现在检出的那一个分支(也就是当前 HEAD 指针所指向的分支)。

image.png

git checkout 分支切换

使用 git checkout命令切换到一个已存在的分支。

$ git checkout dev
$ git hist

image.png

可以看到以切换至 dev 分支, HEAD 指针指向了 dev 分支 👇。

image.png

dev 分支提交

dev分支下修改文件暂存后提交至仓库,查看提交记录,HEAD 分支随着提交操作自动向前移动。

image.png

如图 dev 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。

image.png

切换至master分支

使用 git checkout 命令切换至的master分支。

$ git checkout master
$ git hist --all  

image.png

可以看到 HEAD 指回 master 分支,工作目录也恢复成 master 分支所指向的快照内容。

image.png

项目分叉历史

现在做修改的话,项目将始于一个较旧的版本。 这将会忽略 dev 做的修改,以便于向另一个方向进行开发。

master 分支下修改文件暂存提交后,这个项目的提交历史已经产生了分叉

image.png

使用 git log --pretty=format:'%h --> %p| %ad | %s%d [%an]' --graph --date=short --all 命令查看提交历史、各个分支的指向以及项目的分支分叉情况。

image.png


至此分支的基础概念已经介绍完毕,请大家一定牢记,接下来要基于分支的概念来讲解命令的流程。更复杂的分支管理(工作流)将会在后续文章中进行介绍。

📚参考&关联阅读

"分支",Pro Git
"重置揭密",Pro Git
"git checkout",Pro Git

关注专栏

如果本文对您有所帮助请关注➕、 点赞👍、 收藏⭐!您的认可就是对我的最大支持!

此文章已收录到专栏中 👇,可以直接关注。