Git应用详解第八讲:Git标签、别名与Git gc
前言
这一节主要介绍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 dog
为git log --all --decorate --oneline --graph
的别名,后面会讲解;
随后,查看存储标签文件的.git/refs/tags
目录:
可以看到:
tags
目录下存储着添加的标签文件v1.0
和v2.0
;- 分别打开标签文件
v1.0
和v2.0
,它们的值都是一个SHA1
值,并且与添加标签时所在提交mas2
的SHA1
值6920a6e...
相等。 emm...
等等!并不相等呀,只有v1.0
的值与提交mas2
的SHA1
值相等,而与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
选项中,查看tag
和Releases
信息:
也可以同时推送多个本地标签到远程仓库:
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 status
、git 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
创建master
和dev
两个分支,并将它们推送到远程仓库:然后,给本地仓库
mygit
添加一个轻量级标签v1.0
和一个带有附注的标签v2.0
:
此时.git/refs
目录下的各文件如下所示:
heads
目录存储的是本地分支信息,remote
目录存储的是远程分支信息,tags
目录存储的是标签信息,符合预期。
随后,执行git gc
命令:
再次查看.git/refs
目录:
可以看到refs
目录及其子目录下的文件消失了,但是.git
目录下多了一个packed-refs
文件。事实上,refs
目录下的文件不是消失了,而是被打包到了packed-refs
文件中。打开packed-refs
文件:
可以看到执行git gc
后refs
目录及其子目录下的文件都被压缩打包到packed-refs
文件中了。从图中可以看到轻量级标签v1.0
只占一行,而带附注的标签v2.0
占两行:
- 其中第
6
行和第8
行的SHA1
值是相同的,这是因为两个标签都是给同一次提交上添加的; - 而带附注的标签
v2.0
中的另外一行信息(第7
行)表示的则是tag
对象的SHA1
值;
打包完之后,再次修改文件,或者添加分支,新增的内容还是会在.git/refs
目录下显示,而不会被打包到packed-refs
文件中,需要重新执行git gc
才会被打包。
以上就是本节的全部内容,经过这一节的学习,相信你已经能够熟练运用
Git
标签和别名来提高开发效率了。下一节将会详细介绍git cherry-pick
与git rebase
,我们下一节再见!
Git应用详解第八讲:Git标签、别名与Git gc的更多相关文章
- Git应用详解第七讲:Git refspec与远程分支的重要操作
前言 前情提要:Git应用详解第六讲:Git协作与Git pull常见问题 这一节来介绍本地仓库与远程仓库的分支映射关系:git refspec.彻底弄清楚本地仓库到底是如何与远程仓库进行联系的. 一 ...
- Git应用详解第六讲:Git协作与Git pull常见问题
前言 前情提要:Git应用详解第五讲:远程仓库Github与Git图形化界面 git除了可以很好地管理个人项目外,最大的一个用处就是实现团队协作开发.况且,linus大神开发git的初衷就是为了维护L ...
- Git应用详解第五讲:远程仓库Github与Git图形化界面
前言 前情提要:Git应用详解第四讲:版本回退的三种方式与stash 这一节将会介绍本地仓库与远程仓库的一些简单互动以及几款常用的Git图形化界面,让你更加方便地使用git. 一.Git裸库 简单来说 ...
- Git应用详解第十讲:Git子库:submodule与subtree.md
前言 前情提要:Git应用详解第九讲:Git cherry-pick与Git rebase 一个中大型项目往往会依赖几个模块,git提供了子库的概念.可以将这些子模块存放在不同的仓库中,通过submo ...
- Git应用详解第四讲:版本回退的三种方式与stash
前言 前情提要:Git应用详解第三讲:本地分支的重要操作 git作为一款版本控制工具,其最核心的功能就是版本回退,没有之一.熟悉git版本回退的操作能够让你真真正正地放开手脚去开发,不用小心翼翼,怕一 ...
- git命令详解( 八)
此为记录git的第八篇,前七篇为远程篇,工作中最常用的都在前七篇,因为要在远程分支上合作开发 在提交树上移动 撤销变更 在提交树上移动 在接触 Git 更高级功能之前,我们有必要先学习在你项目 ...
- Git应用详解第九讲:Git cherry-pick与Git rebase
前言 前情提要:Git应用详解第八讲:Git标签.别名与Git gc 这一节主要介绍git cherry-pick与git rebase的原理及使用. 一.Git cherry-pick Git ch ...
- 【Git使用详解】Egit的常用操作详解
常用操作 操作 说明 Fetch 从远程获取最新版本到本地,不会自动merge Merge 可以把一个分支标签或某个commit的修改合并现在的分支上 Pull 从远程获取最新版本并merge到本地相 ...
- Git应用详解第二讲:Git删除、修改、撤销操作
前言 前情提要:Git应用详解第一讲:Git分区,配置与日志 在第一讲中我们对Git进行了简单的入门介绍,相信聪明的你已经了解Git的基本使用了. 这一讲我们来进一步深入学习Git应用,着重介绍Git ...
随机推荐
- drf的频率认证
频率认证源码分析 APIView --->dispatch方法--->self.initial(request, *args, **kwargs)---> self.check_th ...
- SQL数据库-基本操作
SQL教程 整理自:廖雪峰的官方网站-SQL教程 目录 SQL教程 SQL快捷键 1.概述 数据类型 SQL操作数据库的能力 语法特点 2. 安装MySQL 运行MySQL 3. 关系模型 3.1 概 ...
- [模板] dijkstra (堆优化)
复杂度O(mlogn) 输入起点s,可以得到从起点到各点的最短路距离数组dis[i] 过程: 1.初始化:清空标记数组,初始化距离数组设为inf,起点距离设为0,开优先队列,搜索起点 2.搜索:取出队 ...
- 李宏毅老师机器学习课程笔记_ML Lecture 2: Where does the error come from?
引言: 最近开始学习"机器学习",早就听说祖国宝岛的李宏毅老师的大名,一直没有时间看他的系列课程.今天听了一课,感觉非常棒,通俗易懂,而又能够抓住重点,中间还能加上一些很有趣的例子 ...
- Mock测试,结合Fiddler轻松搞定不同场景
在平时测试过程中,总会遇到一些比较难构造的场景.比如不同平台间的同步,异常场景的构造.遇到难构造的场景时,就可以引用Mock来进行单元测试.简言之:mock测试就是在测试过程中,对于某些不容易构造或者 ...
- spring boot项目打war包
1.如果有本地依赖,添加本地依赖到maven <!--lib目录下的jar包--> <dependency> <groupId>com.dm</groupId ...
- BFS与DFS常考算法整理
BFS与DFS常考算法整理 Preface BFS(Breath-First Search,广度优先搜索)与DFS(Depth-First Search,深度优先搜索)是两种针对树与图数据结构的遍历或 ...
- LeetCode#1047-Remove All Adjacent Duplicates In String-删除字符串中的所有相邻重复项
一.题目 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们. 在 S 上反复执行重复项删除操作,直到无法继续删除. 在完成所有重复项删除操作后返回最终的字符串.答案 ...
- Gold30Mins
- gold 30min