git的tag与branch原创

# Git 的tag与branch

# Git 的 commit-id

Git的每一次 commit 都会生成一个由40位SHA-1 摘要算法哈希值(十六进制字符串)组成的 id,我们通常称其为 commit-id 。Git作为一个分布式的版本控制系统,每个人都可以独立创建提交变更,每次提交都形成一个新的 commit-id,为避免冲突,每个 commit-id都不能够重复,是全局唯一的。所以,每一个 commit 的行为都可用commit-id 来准确的标识,使用 git log 命令可以查看所有的commit-id。

# Git 中的 tag

Git的作用是实现源代码的管理,其可实现源代码的跟踪、溯源及回滚,对于其管理代码仓库的文件,记录了每个文件的编辑历史,通过Git的管理,代码仓中每个文件的每次变更,都会以commit-id作为变更的标记和回溯点。通常,我们可以使用Git的命令,切换到对应的commit-id 查看每个文件的变更历史和变更的内容。

在Git 的语境中,使用Git 查看指定commit内容的动作定义为 checkout。checkout 的含义是“checking out”,意味着执行git checkout 命令的这一行为时,将检出一个某次旧的commit 对应的文件覆盖到工作区。checkout 的工作方式如下图所示。

执行命令如下:

git checkout [<commit id>] <paths> 
1

在Git 中为方便某个commit的检出,使用了 tag 参数,Git 通过 tag 指令将对应的commit-id标记为一个方便识别的自定义字符串,tag 比由 40位SHA-1 哈希值组成的commit-id 更容易记忆和识别。Git标签(tag)是Git中非常有用的一种机制,常用于标记重要的版本、方便使用者快速跳转到特定版本、标记里程碑等等。

Git tag 的相关命令如下:

# 当前commit 创建标签 lightweight (轻量级)
git tag 标签名
# 根据commit 创建标签
git tag 标签名 <commit-id>

# 当前commit 创建标签并添加描述 annotated (含附注)
git tag -a 标签名称 -m 附注信息

# 根据commit 创建标签并添加描述
git tag -a 标签名称 <commit-id> -m 附注信息

# 直接列出所有的标签
git tag 
# 按照关键字筛选所有的标签
git tag -l "v4.*"
# 查看标签的提交信息
git show 标签名

# 切换 tag
git checkout 标签名

# 删除指定标签
git tag -d 标签名称

# 将指定的标签上传到远程仓库
git push origin 标签名称
# 将本地仓库中的所有标签上传到远程仓库
git push origin --tags 

# 删除指定标签
git push origin  :regs/tags/标签名称
git push origin --delete 标签名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# Git 中的 branch

在开发的实际工作中,也会存在有同一文件多个不同版本共同存储在一个代码仓库的场景,这就是版本管理控制中的分支管理功能。一个分支代表一条独立的开发线,使用分支意味着你可以从开发主线上分离开来,然后在不影响主线文档版本的同时继续进行开发工作。

Git的代码仓中,git checkout命令可以自由切换分支,其本质仍是一个将commit-id对应内容替换到暂存区和工作区的操作。Git 分支切换后,Git 会用该分支对应commit-id 的内容替换暂存区和工作区的内容, 所以多个分支不需要多个目录,就可使其与检出分支对应commit版本内容保持一致。这之后工作区中的所有变更都会被记录在checkout出来的那个分支上。这一操作可以认为是在选择你希望修改的工作分支。这一特性足以在不用惧怕破坏现有功能的前提下随意实现新的功能开发,还可以让同一个开发者并行展开多个互不相关的新功能开发。这种简单又轻松的分支模型,还促进了更多的协作工作方式的出现。

Git 中的分支,是一个动态的commit-id记录,每次当前分支的commit-id 变化,则Git仓库分支中对应的记录就会变成最新的commit-id。当用户切换分支后,其就会根据commit 对象中的记录,按照父提交节点关系,连接出该分支的所有历史提交。不同分支对应的commit-id 是不同的,所以不同分支的历史提交链就会从最初相同父提交节点分开后变得不同,不同提交快照内的Blob对象也不会受到干扰,进而实现多分支并行开发的效果。

# 创建并切换到新分支
git checkout -b <new-branch>

# 从指定分支创建并切换到新分支
git checkout -b <new-branch> <existing-branch>
# 查看分支
git branch 

# 切换到某分支
git checkout <branch>

# 切换远端分支
## 同步远端仓库信息
git fetch --all
## 切换分支
git checkout <branch>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Git 通常会使用 master 作为分支的默认名字。在有些开发场景,往往会先开发其他分支,例如develop,待到develop分支得到充分测试后再合并到master分支,所以会出现clone 代码是发现是空的,checkout develop 后才会看到代码。

# 克隆并切换到指定分支
git clone -b <branchName> <url>
1
2

# Git 中的tag 与 branch

Git 中的tag 和 branch 都是通过commit-id 做检出的,tag 和 branch的区别在于tag 是具体的一个commit,类似于某一时间点的具体操作,tag与commit-id的映射是静态不变的。而branch则是动态持续向前的操作过程,类似于时间段的一系列操作,branch与commit-id的映射关系是动态变化的,其总会映射用户最后一次的commit-id。

# 检出指定commit 的某个文件
git checkout <commit> <file> 

# 查看指定id属于哪个分支
git branch --contains <commit>

1
2
3
4
5
6

# Git 的基本原理

# Git 仓库结构

Git 分布式的一个重要特征是在本地有一个完整的代码仓库,Git的本地代码仓库是存储在 .git 文件夹中的,通过这个仓库,Git 就可以完全离线化操作。在这个本地化的仓库中存储了 Git 所有的模型对象。下面是 Git 仓库的相关说明如下:

# Git 基本对象

Git 实现文件管理和跟踪是在每次commit变更后在本地的.git 文件夹中将当前commit 的变化进行存储生成一个快照,在通过切换不同的commit-id时,执行检出操作,将快照从本地仓库恢复到用户的暂存区和工作区。Git 中主要有四个对象 Blob、Tree、Commit、Tag,实现快照信息的记录。

  • Tree,对应的是快照中文件系统的的目录,主要包含每个文件的各种信息,如文件文件名、类型、权限信息、对应的 Git 对象类型、SHA-1值等。

  • Commit,对应的一次提交,记录每次 commit 的关联信息,该关联信息包含了本次修改的作者、本次提交的人、一个指向暂存内容快照的指针(即,本次提交的 tree 的 SHA-1 值),以及本次提交对象的父提交节点指针(可能是0个、1个、多个)。

  没有父提交节点指针的情况:首次提交,所以没有直接祖先。
  一个父提交节点指针的情况:普通提交,即在某分支上进行提交操作,只有一个祖先。
  多个父提交节点指针的情况:分支合并,由两个分支或者多个合并产生的提交会拥有多个祖先提交。
1
2
3
  • Blob,对应用户实际操作的单个文件,它存储的是单个文件的内容,一般是二进制数据文本,不包含其他的信息。

  • tag 是与某一commit-id的静态映射记录,tag名是全仓库唯一且不可重复的。

可以用 git cat-file -t 查看每个 SHA-1 的类型,用 git cat-file -p 查看每个对象的内容和简单的数据结构。git cat-file 是底层核心命令。所有对象模型之间的关系大致如下:

Initializing...

最近更新
01
阿里云SLS日志服务的数据脱敏及安全管理 原创
03-21
02
云平台的成本管理 原创
03-13
03
可观测性监控中的数据安全 - DataDog中的监控数据脱敏实战 原创
03-04
更多文章>
×