git分支详解
# 1 概念
在任何代码管理工具中, 分支都是一个非常重要的概念
# 1) 什么是分支
首先, 我们简单的复习一下什么是分支
分支(branch)是一个比较抽象的概念, 杰哥找了很久也没有一个非常好的确切定义.
给一个自己的定义
分支是主线某个状态的一个复制, 在不影响主线情况下, 可以有新的变化
我们通过实际例子来理解
我们的工作一般都是在一条主线(master)上进行, 每一次提交会形成一个commit对象, 如下图所示
客户提出了一个新的需求, 而这个需求的开发需要一段时间才能完成.
为了不影响主线的稳定性和持续进行. 我们会怎么做?
我们可以把整个项目复制一份, 在复制的项目上开发新功能, 开发完成通过测试后, 再将改动的代码整合回主线.
那么, 这个复制出来的项目就是一个分支
# 2) 分支的作用
现在, 我们了解到分支的提出主要是为了开发新功能而不影响主线的正常运行
通过上面的例子, 我们大概可以知道
- 分支和主线有一部分内容是相同的, 有一部分是不同的
- 在分支上可以做新的开发, 而不会影响到原来的主线
- 在分支上开发完成后, 通常还是要将改动合并回主线
# 2 相关命令
# 查看已有分支
git branch
# 创建分支
git branch 分支名
# 切换分支
git checkout 分支名
# 合并分支
git merge
2
3
4
5
6
7
8
# 3 分支的本质
git branch可以查看当前所有的分支, 本质上是显示.git/refs/heads
目录下的文件.
查看文件具体的内容
- 文件名(dev, master)表示一个分支
- 文件的内容是最近一次commit对象的Hash串
因此, 我们得出一个重要的结论
提示
Git中的分支本质上是一个指针, 指向该工作流中最近的一次commit
# 4 命令详解
# 1) 准备
先做3次提交
通过git log --oneline
查看commit对象
分析
图解
# 2) 创建分支
使用git branch 分支名
可以基于现有的commit对象, 在.git/refs/heads
下产生一个文件
当执行git branch dev
时创建了一个dev分支
本质上就是在.git/refs/heads
目录下创建了一个文件
- 文件名: dev
- 文件内容: d434d9f
图解
# 3) 切换分支
HEAD指针永远指向当前所在的分支
执行git checkout
的作用之一, 就是改变HEAD的指向, 本质就是修改了HEAD文件中的内容
图解
# 4) 在分支上工作
把分支切换到dev
后, 我们就可以在dev分支上进行修改, 这些修改是不会影响到原来的master分支的
图解
此时, 我们可以通过git chekout
在分支间来回切换, 工作区的内容也会随之变化
# 5) Fast-forward合并
此时, 如果我们要把在dev分支上的改动合并回master, 需要
- 切换到master分支
- 执行merge
演示
图解
像这样的合并是比较快的, 叫做Fast-forward(快速向前)的合并方式, 只是指针的移动
# 6) Three-way合并
在上面的例子中. 我们基于master的c3 commit创建了dev分支.
在后面仅仅只在dev上改动了代码. master一直指向c3 commit.
这样合并时就非常简单, 也很快, 只需要将master指针指向新的c4 commit就可以. 这种方式就是Fast-forward
但是如果, master和dev同时都有改动, 将会如何呢?看下面的例子
# 步骤一
在master分支创建一个文件, 并提交
# 步骤二
切换到dev分支, 创建dev.txt文件并提交
执行命令, 查看log
git log --oneline --graph --all
- --graph: 以图形展示log
- --all: 显示所有分支
图解
# 步骤三
切换到master, 执行合并
此时, 会自动创建一个新的commit对象e02bdf6
, 同时指向99fe8a
和1740e
图解
有的地方, 把这种合并称为Three-way(三方合并)