前言

前情提要:Git应用详解第七讲:Git refspec与远程分支的重要操作

这一节主要介绍Git标签、别名与Git的垃圾回收机制。

一、Git标签(tag)

1.标签的实质

标签与分支十分相似,都是指向某一次提交;并且,它们的值都为各自指向提交的SHA1值;但是,不同于会随着提交的变化而变化的分支,一旦给某次提交添加了标签,该标签就永远不会发生变化。

注意:标签标识的是某一次提交,这次提交可以是任何分支上的任何一次提交。

两类标签

Git标签有两种:

  • 轻量级标签lightweight):不可添加注释;
  • 带有附注的标签annotated):可以添加注释;

Annotated tags are meant for release while lightweight tags are meant for private or temporary object labels.

以上是git官方文档对两种标签的说明,大意是:带注释的标签用于发布,而轻量级标签则用于私人或临时对象。

什么时候打标签呢?

  • 版本发布:一般master分支都会作为项目的发布分支,当项目开发到了一个成熟的阶段,准备在master分支进行发布时。一般都会在master分支的当前提交上打上一个类似"v1.2"的标签;

    比如Vue框架:

    可以看到有许多标签,并且可以在releases选项中查看标签和发布版本:

  • 版本管理:可以通过标签的形式记录项目某一阶段的状态,方便管理;

    比如管理学习微信小程序时每个知识点的代码:

查看标签文件

如下图所示,分别给master分支的提交mas2添加一个轻量级标签v1.0和一个带有附注的标签v2.0

git doggit log --all --decorate --oneline --graph的别名,后面会讲解;

随后,查看存储标签文件的.git/refs/tags目录:

可以看到:

  • tags目录下存储着添加的标签文件v1.0v2.0
  • 分别打开标签文件v1.0v2.0,它们的值都是一个SHA1值,并且与添加标签时所在提交mas2SHA16920a6e...相等。
  • emm...等等!并不相等呀,只有v1.0的值与提交mas2SHA1值相等,而与v2.0的值并不相等!
  • 为什么给同一次提交mas2添加的标签,它们的SHA1值会不相等呢?这是因为v1.0是轻量级标签,而v2.0是带有附注的标签。

虽然两个标签标记的都是同一次提交,但是它们的构造不一样:

  • 轻量级标签v1.0直接将这次提交的SHA1值作为自己的SHA1值;

  • 而带附注的标签v2.0会创建一个tag对象,它的SHA1值是tag对象的SHA1值;

这就是轻量级标签与带有附注标签的区别。不过这两个标签仍然会指向同一次提交,如下图所示:

2.创建标签

git tag <tag_name>

创建一个轻量级标签:

git tag -a <tag_name> -m '注释'

创建一个带有附注的标签:

3.查看标签

git tag

显示添加的所有标签:

也可以添加--list参数:

如下图所示:切换了分支tag仍然存在,说明tag与分支并没有关系,它标识的是某次特定的提交:

git show <tag_name>

如图所示,在master分支上进行两次提交,每次为文件test.txt添加一行内容并且打上标签。其中v1.0为轻量级标签,v2.0为带有附注的标签:

随后,使用git show查看标签的内容:

  • 轻量级标签:

    如图所示,该指令会显示标签v1.0所指向的提交;并且,会输出标签指向提交与上一次提交的比较结果;由于标签v1.0指向的提交为master分支的第一次提交,所以上一次提交为null。因此比较结果显示:相比于上一次提交,标签指向的提交1st在文件test.txt中新增了一行1st

  • 带注释的标签:

    相比于轻量级标签,带附注的标签是一个对象,可以存储附注和打标签的人和时间等信息,所以显示的信息多一些;从图中的比较结果可知,相比于上一次提交1st,标签v2.0指向的提交2nd为文件test.txt新增了一行2nd

4.查找标签

git tag -l <tag_name>

该方式支持正则表达式查找;

如上图所示:

  • v*表示搜索所有以v开头的标签;
  • ?2*表示搜索任意开头,但包含2的标签;

5.将标签推送到远程

要将标签推送到远程仓库,首先要建立本地仓库与远程仓库的联系,比如可以采用:

git push -u origin master

建立本地master分支与远程master分支的联系,并进行一次推送:

git push origin <tag_name>

这种方法可以推送指定的本地标签到远程仓库,例如将本地master分支上的标签v1.0推送到远程仓库:

执行上述指令后,对应的远程仓库gitTest中就会出现相应的tag信息了:

也可以在releases选项中,查看tagReleases信息:

也可以同时推送多个本地标签到远程仓库

git push origin  v2.0 v3.0

以上的命令都是简写形式,完整写法为:

git push origin refs/tags/v4.0:refs/tags/v4.0

git push origin --tag

该方法可以一次性推送所有的本地标签到远程仓库:

也可以采用简写命令:

//下面的tag可以写成tags,效果一样
git push --tag

6.删除远程标签

当然,我们可以直接在远程仓库上删除远程标签。但是,最好的方式还是采用命令行进行删除。删除远程标签的方法与删除远程分支的方法非常类似,同样有两种方法:

git push origin :<tag_name>

这种方法相当于推送一个空的标签到远程仓库,由此达到删除的效果。比如删除远程仓库中的标签v3.0

git push origin :v3.0

这样远程仓库中的标签V3.0就被删除了:

但是本地仓库中对应的标签V3.0并没有被删除:

上述指令为简写,完整写法如下

git push origin :refs/tags/v3.0

git push origin --delete <tag_name>

该方法采用了更加语义化的参数--delete,实现远程标签的删除:

git push origin --delete v2.0

同样成功地删除了远程仓库中的标签v2.0

但是,本地的标签v2.0也没有被删除:

采用下列的完整写法,效果是一样的:

git push origin --delete tag v2.0

不难发现,删除远程分支远程标签的方法是一样的。

7.删除本地标签

git tag -d <tag_name>

如通过以下命令删除标签v3.0

git tag -d v3.0

8.切换标签

git checkout <tag_name>

如图所示,在master分支上进行了三次提交,并且添加了相应的标签:

当我们通过checkout命令切换到标签v2.0时:

可见,会出现游离的提交。此时查看各分支状态:

如上图所示,当前处于标签v2.0指向的提交,并且切换标签的过程中改变了HEAD指针的指向。但是,并没有改变分支master的指向。过程如下图所示:

也就是说,切换标签与使用reset进行版本回退十分相似。只不过切换标签只改变了HEAD指针的指向,会造成游离的提交。若有需要可以创建一个新分支进行保存。

9.拉取标签

在下图所示的情况中,本地仓库mygit与远程仓库有公共的提交历史(同源),并且不发生合并冲突的情况下(具体可参考Git应用详解第六讲:Git协作与Git pull常见问题):

可以直接通过git pull将远程仓库的标签拉取下来,并创建本地仓库中没有的标签:

二、Git别名

1.设置git命令别名

git config <作用域> alias.<别名> '<命令>'

别名就是一个替代,使用一个简短的字符串来代替常用的长命令。比如可以通过如下命令,使用别名bra来替代branch命令:

git config --global alias.bra branch

当命令较为简短时,可以省略命令两边的单引号:

在上述命令中:

  • --global表示设置的别名作用域为系统用户,即该用户对所有的git仓库都可以使用这个别名;其余还有仓库作用域--loacl,系统作用域--system

  • alias.br表示更改别名为br

  • 再往后的branch表示需要起别名的命令,可以是带参数的长命令,此时不能省略命令两边的单引号:

    git config --global alias.dog 'log --all --decorate --oneline --graph'

由于上面配置的别名作用域为系统用户,该配置会写入gitconfig配置文件。打开该文件可以看到写入的别名配置

补充:使用vi ~/.gitconfig可以直接打开gitconfig这个文件(记得加点),无论当前所处的路径是什么;

也就是说可以直接通过修改gitconfig文件的alias选项来设置别名,但是不建议

这样,通过别名就可以简化一些常用的命令了,比如git statusgit checkout等:

2.设置外部命令别名

gitk这样的外部命令,是没有git前缀的。设置别名的方法与设置git提供的命令有所不同,要按照如下格式设置:

git config <作用域> alias.<别名> '<!外部命令>'
  • 感叹号表示这是一个外部命令;
  • 注意要加上单引号,不用加git前缀;

比如在系统用户作用域下,将git ui设置为gitk的别名:

 git config --global alias.ui '!gitk'

设置完成后,该配置会被写入系统用户的配置文件gitconfig中:

随后直接使用git ui便能打开gitk界面:

补充:设置了别名后,原来的命令仍然有效。

三、垃圾回收:Git gc

所谓gc就是垃圾回收机制,实际使用较少;它的作用是清理不必要的文件并优化本地存储库

为了演示它的作用,设置以下测试环境:

  • 首先,在本地仓库mygit创建masterdev两个分支,并将它们推送到远程仓库:

  • 然后,给本地仓库mygit添加一个轻量级标签v1.0和一个带有附注的标签v2.0

此时.git/refs目录下的各文件如下所示:

heads目录存储的是本地分支信息,remote目录存储的是远程分支信息,tags目录存储的是标签信息,符合预期。

随后,执行git gc命令:

再次查看.git/refs目录:

可以看到refs目录及其子目录下的文件消失了,但是.git目录下多了一个packed-refs文件。事实上,refs目录下的文件不是消失了,而是被打包到了packed-refs文件中。打开packed-refs文件:

可以看到执行git gcrefs目录及其子目录下的文件都被压缩打包packed-refs文件中了。从图中可以看到轻量级标签v1.0只占一行,而带附注的标签v2.0占两行:

  • 其中第6行和第8行的SHA1值是相同的,这是因为两个标签都是给同一次提交上添加的;
  • 而带附注的标签v2.0中的另外一行信息(第7行)表示的则是tag对象的SHA1值;

打包完之后,再次修改文件,或者添加分支,新增的内容还是会在.git/refs目录下显示,而不会被打包到packed-refs文件中,需要重新执行git gc才会被打包。

以上就是本节的全部内容,经过这一节的学习,相信你已经能够熟练运用Git标签和别名来提高开发效率了。下一节将会详细介绍git cherry-pickgit rebase,我们下一节再见!

Git应用详解第八讲:Git标签、别名与Git gc的更多相关文章

  1. Git应用详解第七讲:Git refspec与远程分支的重要操作

    前言 前情提要:Git应用详解第六讲:Git协作与Git pull常见问题 这一节来介绍本地仓库与远程仓库的分支映射关系:git refspec.彻底弄清楚本地仓库到底是如何与远程仓库进行联系的. 一 ...

  2. Git应用详解第六讲:Git协作与Git pull常见问题

    前言 前情提要:Git应用详解第五讲:远程仓库Github与Git图形化界面 git除了可以很好地管理个人项目外,最大的一个用处就是实现团队协作开发.况且,linus大神开发git的初衷就是为了维护L ...

  3. Git应用详解第五讲:远程仓库Github与Git图形化界面

    前言 前情提要:Git应用详解第四讲:版本回退的三种方式与stash 这一节将会介绍本地仓库与远程仓库的一些简单互动以及几款常用的Git图形化界面,让你更加方便地使用git. 一.Git裸库 简单来说 ...

  4. Git应用详解第十讲:Git子库:submodule与subtree.md

    前言 前情提要:Git应用详解第九讲:Git cherry-pick与Git rebase 一个中大型项目往往会依赖几个模块,git提供了子库的概念.可以将这些子模块存放在不同的仓库中,通过submo ...

  5. Git应用详解第四讲:版本回退的三种方式与stash

    前言 前情提要:Git应用详解第三讲:本地分支的重要操作 git作为一款版本控制工具,其最核心的功能就是版本回退,没有之一.熟悉git版本回退的操作能够让你真真正正地放开手脚去开发,不用小心翼翼,怕一 ...

  6. git命令详解( 八)

    此为记录git的第八篇,前七篇为远程篇,工作中最常用的都在前七篇,因为要在远程分支上合作开发     在提交树上移动 撤销变更 在提交树上移动 在接触 Git 更高级功能之前,我们有必要先学习在你项目 ...

  7. Git应用详解第九讲:Git cherry-pick与Git rebase

    前言 前情提要:Git应用详解第八讲:Git标签.别名与Git gc 这一节主要介绍git cherry-pick与git rebase的原理及使用. 一.Git cherry-pick Git ch ...

  8. 【Git使用详解】Egit的常用操作详解

    常用操作 操作 说明 Fetch 从远程获取最新版本到本地,不会自动merge Merge 可以把一个分支标签或某个commit的修改合并现在的分支上 Pull 从远程获取最新版本并merge到本地相 ...

  9. Git应用详解第二讲:Git删除、修改、撤销操作

    前言 前情提要:Git应用详解第一讲:Git分区,配置与日志 在第一讲中我们对Git进行了简单的入门介绍,相信聪明的你已经了解Git的基本使用了. 这一讲我们来进一步深入学习Git应用,着重介绍Git ...

随机推荐

  1. MySQL:REPLACE函数的使用

    原文链接 REPLACE函数功能 REPLACE(columnName, search_str, replace_str) 查找columnName字段中所有search_str,并替换为replac ...

  2. golang超级mapper包 - coven

    coven介绍 你可以把它理解成.NET 的 AutoMapper,java的modelmapper 一个快速的转换器去,支持结构到结构,切片到切片和映射到映射非反射转换,类型与嵌套指针支持. 不支持 ...

  3. Django 支付宝付款接口的使用

    我们在开发的过程中经常会碰到调用微信或者支付宝接口进行付款,付款完成之后,如果用户绑定了我的账号,我只要有活动了,就要给这个关注我的用户推动消息,让用户知道,比如说,我们经常会关注一些公众号,然后这些 ...

  4. Django之模板层细说

    django的模板层,基于我们前面学习的内容,也知道主要语法是{{变量相关}}{%逻辑相关%},那么具体还有哪些内容呢?且听我娓娓道来. 模板层(模板语法) 标签 过滤器 自定义标签,过滤器,incl ...

  5. MySQL数据库升级

    当前不少系统的数据库依旧是MySQL5.6,由于MySQL5.7及MySQL8.0在性能及安全方面有着很大的提升,因此需要升级数据库.本文通过逻辑方式.物理方式原地升级来介绍MySQL5.6 升级至M ...

  6. CF1326C Permutation Partitions 题解,

    原题链接 简要题意: 给定一个 \(1\) ~ \(n\) 的置换,将数组分为 \(k\) 个区间,使得每个区间的最大值之和最大.求这个值,和分区的方案数. 关键在于 \(1\) ~ \(n\) 的置 ...

  7. Vue组件通信方式全面详解

    vue组件通信方式全面详解 众所周知,Vue主要思想就是组件化开发.因为,在实际的项目开发中,肯定会以组件的开发模式进行.形如页面和页面之间需要通信一样,Vue 组件和组件之间肯定也需要互通有无.共享 ...

  8. ICCV 2019|70 篇论文抢先读,含目标检测/自动驾驶/GCN/等(提供PDF下载)

    虽然ICCV2019已经公布了接收ID名单,但是具体的论文都还没放出来,为了让大家更快得看论文,我们汇总了目前已经公布的大部分ICCV2019 论文,并组织了ICCV2019论文汇总开源项目(http ...

  9. .NET 5 中的正则引擎性能改进(翻译)

    前言 System.Text.RegularExpressions 命名空间已经在 .NET 中使用了多年,一直追溯到 .NET Framework 1.1.它在 .NET 实施本身的数百个位置中使用 ...

  10. unix中数据缓冲区高速缓冲的设计

    目录 1. 概述 2. 缓冲区的设计 2.1 缓冲区头部 2.2 缓冲区的结构 2.3 缓冲区的检索算法 2.3. 申请一个缓冲区算法 getblk 2.3.2 释放一个缓冲区算法 brelse 2. ...