Git应用详解第八讲:Git标签、别名与Git gc

  • Post author:
  • Post category:其他




前言

这一节主要介绍

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

    框架:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rS9higAI-1587204460088)( http://ahuntsun.gitee.io/blogimagebed/img/git/lesson8/1.png)]

    可以看到有许多标签,并且可以在

    releases

    选项中查看标签和发布版本:

    image-20200418125721571

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

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

    image-20200418165957032




查看标签文件

如下图所示,分别给

master

分支的提交

mas2

添加一个轻量级标签

v1.0

和一个带有附注的标签

v2.0

image-20200418122516160


git dog



git log --all --decorate --oneline --graph

的别名,后面会讲解;

随后,查看存储标签文件的

.git/refs/tags

目录:

image-20200418123105227

可以看到:


  • 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

    值;

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

image-20200418124847587



2.创建标签



git tag <tag_name>

创建一个轻量级标签:

image-20200311143441005




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

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

image-20200311143555121



3.查看标签



git tag

显示添加的所有标签:

image-20200418140044357

也可以添加

--list

参数:

image-20200418140101235

如下图所示:切换了分支

tag

仍然存在,说明

tag

与分支并没有关系,它标识的是某次特定的提交:

image-20200418140210619




git show <tag_name>

如图所示,在

master

分支上进行两次提交,每次为文件

test.txt

添加一行内容并且打上标签。其中

v1.0

为轻量级标签,

v2.0

为带有附注的标签:

image-20200418164206660

随后,使用

git show

查看标签的内容:


  • 轻量级标签:

    image-20200418164502188

    如图所示,该指令会显示标签

    v1.0

    所指向的提交;并且,会输出标签指向提交与上一次提交的比较结果;由于标签

    v1.0

    指向的提交为

    master

    分支的第一次提交,所以上一次提交为

    null

    。因此比较结果显示:相比于上一次提交,标签指向的提交

    1st

    在文件

    test.txt

    中新增了一行

    1st


  • 带注释的标签:

    image-20200418165301312

    相比于轻量级标签,带附注的标签是一个对象,可以存储附注和打标签的人和时间等信息,所以显示的信息多一些;从图中的比较结果可知,相比于上一次提交

    1st

    ,标签

    v2.0

    指向的提交

    2nd

    为文件

    test.txt

    新增了一行

    2nd



4.查找标签



git tag -l <tag_name>

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

image-20200418140732354

如上图所示:


  • v*

    表示搜索所有以

    v

    开头的标签;

  • ?2*

    表示搜索任意开头,但包含

    2

    的标签;


5.将标签推送到远程

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

git push -u origin master

建立本地

master

分支与远程

master

分支的联系,并进行一次推送:

image-20200418143423585




git push origin <tag_name>

这种方法可以推送指定的本地标签到远程仓库,例如将本地

master

分支上的标签

v1.0

推送到远程仓库:

image-20200418143541273

执行上述指令后,对应的远程仓库

gitTest

中就会出现相应的

tag

信息了:

image-20200418143927912

也可以在

releases

选项中,查看

tag



Releases

信息:

image-20200418144230515

image-20200418144207107


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

git push origin  v2.0 v3.0

image-20200418144612359

以上的命令都是简写形式,

完整写法为:

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

image-20200418144755135




git push origin --tag

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

image-20200418144952994

也可以采用简写命令:

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

image-20200418145049074



6.删除远程标签

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




git push origin :<tag_name>

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

v3.0

git push origin :v3.0

image-20200418154504982

这样远程仓库中的标签

V3.0

就被删除了:

image-20200418154554319

但是本地仓库中对应的标签

V3.0

并没有被删除:

image-20200418154631370

上述指令为简写,

完整写法如下

git push origin :refs/tags/v3.0

image-20200418154906969




git push origin --delete <tag_name>

该方法采用了更加语义化的参数

--delete

,实现远程标签的删除:

git push origin --delete v2.0

image-20200418155134748

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

v2.0

image-20200418155216230

但是,本地的标签

v2.0

也没有被删除:

image-20200418155311429

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

git push origin --delete tag v2.0

image-20200418155513090

不难发现,删除

远程分支



远程标签

的方法是

一样

的。



7.删除本地标签



git tag -d <tag_name>

如通过以下命令删除标签

v3.0

git tag -d v3.0

image-20200418155616562



8.切换标签



git checkout <tag_name>

如图所示,在

master

分支上进行了三次提交,并且添加了相应的标签:

image-20200418161353146

当我们通过

checkout

命令切换到标签

v2.0

时:

image-20200418161526176

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

image-20200418161655468

如上图所示,当前处于标签

v2.0

指向的提交,并且切换标签的过程中改变了

HEAD

指针的指向。但是,并没有改变分支

master

的指向。过程如下图所示:

image-20200418162458123

也就是说,切换标签与使用

reset

进行版本回退十分相似。只不过切换标签只改变了

HEAD

指针的指向,会造成游离的提交。若有需要可以创建一个新分支进行保存。



9.拉取标签

在下图所示的情况中,本地仓库

mygit

与远程仓库有公共的提交历史(同源),并且不发生合并冲突的情况下(具体可参考

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

):

image-20200418160517111

可以直接通过

git pull

将远程仓库的标签拉取下来,并创建本地仓库中没有的标签:

image-20200418160737829



二、

Git

别名



1.设置

git

命令别名



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

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

bra

来替代

branch

命令:

git config --global alias.bra branch 

image-20200417184645237

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

image-20200417184803691

在上述命令中:


  • --global

    表示设置的别名作用域为系统用户,即该用户对所有的

    git

    仓库都可以使用这个别名;其余还有仓库作用域

    --loacl

    ,系统作用域

    --system


  • alias.br

    表示更改别名为

    br

  • 再往后的

    branch

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

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

    image-20200413171109680

由于上面配置的别名作用域为系统用户,该配置会写入

gitconfig

配置文件。打开该文件可以看到写入的

别名配置

**补充:**使用

vi ~/.gitconfig

可以直接打开

gitconfig

这个文件(记得加点),无论当前所处的路径是什么;

image-20200417185537264

也就是说可以直接通过修改

gitconfig

文件的

alias

选项来设置别名,但是

不建议

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

git status



git checkout

等:

image-20200417185854925



2.设置外部命令别名



gitk

这样的外部命令,是没有

git

前缀的。设置别名的方法与设置

git

提供的命令有所不同,要按照如下格式设置:




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

  • 感叹号表示这是一个外部命令;
  • 注意要加上单引号,不用加

    git

    前缀;

比如在系统用户作用域下,将

git ui

设置为

gitk

的别名:

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

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

gitconfig

中:

image-20200417190632295

随后直接使用

git ui

便能打开

gitk

界面:

image-20200417190558949

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



三、垃圾回收:

Git gc

所谓

gc

就是垃圾回收机制,实际使用较少;它的作用是

清理不必要的文件并优化本地存储库

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

  • 首先,在本地仓库

    mygit

    创建

    master



    dev

    两个分支,并将它们推送到远程仓库:

    image-20200418105755292

  • 然后,给本地仓库

    mygit

    添加一个轻量级标签

    v1.0

    和一个带有附注的标签

    v2.0

    image-20200418110041381

此时

.git/refs

目录下的各文件如下所示:

image-20200418110228125


heads

目录存储的是本地分支信息,

remote

目录存储的是远程分支信息,

tags

目录存储的是标签信息,符合预期。

随后,执行

git gc

命令:

image-20200418110332080

再次查看

.git/refs

目录:

image-20200418110544449

可以看到

refs

目录及其子目录下的文件消失了,但是

.git

目录下多了一个

packed-refs

文件。事实上,

refs

目录下的文件不是消失了,而是被打包到了

packed-refs

文件中。打开

packed-refs

文件:

image-20200418111206150

可以看到执行

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

,我们下一节再见!



版权声明:本文为qq_43425487原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。