
# 管理Tag
Tag是Git提供的帮助团队进行版本管理的工具，用户可以使用GitTag标记提交，从而将项目中的重要的版本管理起来，以便日后精确检索历史版本。
Tag会指向一个commit，就像一种引用，无论后续版本怎么变化，它永远指向这个commit不会变化，相当于一个被永远保存的版本快照（只有手动删除时才会被剔除版本库）。
在使用Git进行代码管理时，用户可以根据每次提交（commit）的ID去查找、追述历史版本，这个ID是一长串编码（如下图中所示），相对于熟知的"V 1.0.0"这样的版本号，CommitID不便于记忆，同时也不具备可识别性，这时就可以给重要的版本打上Tag，给它一个相对友好的名称（比如"myTag_V1.0.0"、"首个商业化版本"）以便更容易记住和追溯它。
![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251195589.png "点击放大")
#### 在控制台为最新的提交创建Tag
1. 用户进入仓库列表，单击仓库名称进入仓库详情。
2. 单击"代码"页签下的**"Tags"**子页签，在这里可以看到Tag列表。
3. 单击"新建"按钮，弹出新建Tag页面如下图，选择要基于哪条分支或Tag的最新版本进行Tag的创建。Tag名称须满足如下要求： 
   - 不支持以"-"、"."、"refs/heads/"、"refs/remotes/"、"/"开头。
   
   - 不支持空格和\[ \\ \< \~ \^ : ? \* ! ( ) ' " \| $ \& ;等特殊字符。
   
   - 不支持以"."、"/"、".lock"结尾。
   
   - 不能有两个连续的点".."。
   
   - 不能包含序列"@{"。
   
   
   如果在描述中输入信息会生成附注Tag，不输入则生成轻量Tag。当仓库中已存在同名称的分支、Tag或者上级分支、Tag时，则该Tag不可被创建。
   ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155788.png "点击放大")
   
   
4. 单击"确定"按钮，即可基于某个分支的最新版本生成Tag，页面跳转到Tag列表。
 
#### 在控制台为历史版本创建Tag
1. 进入仓库列表。
2. 单击仓库名称进入仓库详情。在"代码"页签中，单击"文件 \> 历史"页签。
3. 在历史列表中的某条提交记录中，单击![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216315596.png)，选择**"新建Tag"**，弹出为历史版本新建Tag的弹窗。如果在描述中输入信息会生成附注Tag，不输入则生成轻量Tag。
4. 单击"确定"按钮，即可基于某个指定历史版本生成Tag，页面跳转到Tag列表。
 
#### 在控制台管理Tag
- 在控制台的Tag列表中，可查看该远程仓库中的全量Tag并进行如下操作。
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216315624.png "点击放大")
  - 单击Tag名称，可跳转到该Tag对应版本的文件列表。
  
  - 单击**"提交号"**，跳转到该次提交（commit）的详情页面。
  
  - 单击![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216315632.png)，可下载tar.gz或zip格式的被Tag版本的文件包。**如果仓库设置IP白名单，则只有IP白名单内的机器才可以在界面下载仓库源码，如果仓库没有设置IP白名单，则均可在界面下载仓库源码。**
  
  - 单击![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251275457.png)，可以将此Tag从代码托管仓库删除（想从本地删除请clone、pull或本地手动-d删除）。
    

- 在控制台创建分支时，用户可以选择基于某个Tag去创建分支。

- 在控制台中，单击**"代码"** 页签，单击目标文件的"文件名称"，单击文件的**"对比"** 页签，可在该文件的提交记录之间做差异对比。
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155812.png "点击放大")
  
 
#### Tag的分类
两种Tag都可进行版本标识，**附注Tag**包含了更多的信息，同时其在Git中也以更稳定安全的结构被存储，被更多的应用于大型项目中。
Git提供的Tag类型分为两种：
- **轻量级Tag：** 仅是一个指向特定commit的引用，可以理解为给特定commit起了一个别名。
  ```
  git tag <用户给Tag起的名称>
  ```
  如下图是一个轻量Tag被查看详情时的显示内容，可以看到它其实就是一次commit的别名。
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251195577.png "点击放大")
  

- **附注Tag：** 指向一个特定的commit，但在Git中被作为一个完整对象存储，相比于轻量Tag，附注Tag可以为Tag附上说明，类似代码的注释功能，方便注解Tag。在Tag信息的记录中，除包括Tag名、附注Tag说明外，同时包含了打Tag者名字、电子邮件地址、打Tag时间/日期。
  ```
  git tag -a  <用户给Tag起的名称> -m <"用户给Tag编写的说明">
  ```
  如下图是一个附注Tag被查看详情时的显示内容，它指向了一次commit，相对于轻量Tag它包含了更多的信息。
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251195601.png "点击放大")
  
 
#### 关于Tag的常用Git命令
- **新建轻量Tag**
  ```
  git tag <用户给Tag起的名称>       #为当前最新的提交打上轻量Tag
  ```
  示例如下：
  ```
  git tag myTag1                   #在当前版本的仓库中创建一个新的Tag
  ```
  
- **新建附注Tag**
  ```
  git tag -a  <用户给Tag起的名称> -m <"用户给Tag编写的说明">          #为当前最新的提交打上附注Tag
  ```
  示例如下：
  ```
  git tag -a myTag2 -m "This is a tag." #为当前最新的提交打上名称为 myTag2 的附注Tag,Tag的备注信息为 This is a tag.
  ```
  
- **为历史版本打Tag**
  也可以对于历史版本打Tag，只要使用给git log命令获取到历史版本的commit ID就行，以附Tag为例，其操作如下。
  ```
  git log                 #会显示历史提交信息,获取commitID如下图,只取前几位即可，按 q 返回
  ```
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251275473.png "点击放大")
  ```
  git tag -a historyTag -m "Tag a historical version." 6a5b7c8db    #为commitID为6a5b7c8d开头的历史版本打上一个Tag，名称为 historyTag，备注为 Tag a historical version.
  ```
  
- **新建Tag的常见问题**
  - 执行完新建Tag操作，如果无回显则是创建成功，如果有回显一般是Tag名称重复（回显如下图），更换Tag名称重新执行即可。 ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155796.png "点击放大")
    
  
  - Git支持为一次commit打上多个Tag，其在log中显示如下图，Tag名不能重复。 ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155816.png "点击放大")
    
   
 
- **查看本地仓库的Tag列表**
  将目前仓库内的Tag的名称全部显示出来，在使用时可对其添加参数达到进行过滤的效果 。
  ```
  git tag
  ```
  
- **查看指定Tag详情**
  ```
  git show <用户想查看的Tag的名称>
  ```
  示例如下：
  将名称为 myTag1 的Tag详细信息和其指向的commit的信息显示出来，其执行回显示例如下。
  ```
  git show myTag1
  ```
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251195593.png "点击放大")
  
- **将本地Tag推送到远程仓库**
  - 默认情况下，将本地仓库推送（git push）到远程仓库时，不会把Tag一起推送；当从远程仓库同步内容到本地时（clone、pull），会自动将远程仓库的Tag同步到本地仓库，所以如果想将本地Tag分享项目里的其他人时，需要使用单独的Git命令，其用法如下。
    ```
    git push <远程仓库地址或别名> <用户想推送的Tag的名称>      #将指定Tag推送到远程仓库
    ```
    示例如下：
    将名为 myTag1 的本地Tag推送到别名为 origin 的远程仓库。
    ```
    git push origin myTag1
    ```
    
  
  - 执行下述命令，用户可以把本地所有新增Tag推送到远程仓库。**当用户在远程仓库建立了一个Tag，又在本地仓库建立了一个同名的Tag，这时在推送时会失败（出现Tag冲突），只能删除其一，再次推送。**
    ```
    git push  <远程仓库地址或别名> --tags
    ```
    
   
- **删除本地Tag**
  ```
  git tag -d <用户要删除的Tag的名称>
  ```
  其应用示例如下图，删除本地名为 tag1 的Tag，删除成功。
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155784.png "点击放大")
  
- **删除远程仓库Tag**
  如同Tag的创建需要单独手动推送，Tag的删除，也需要手动推送，其具体用法如下。
  ```
  git push <远程仓库地址或别名> :refs/tags/<用户要删除的Tag的名称>
  ```
  示例如下，图为删除成功。
  ```
  git push HTTPSOrigin :refs/tags/666               #删除别名为 HTTPSOrigin 的远程仓库的名为 666 的Tag
  ```
  ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251275465.png "点击放大")
  
#### 使用Tag找回历史版本
本章节可帮助用户理解通过Tag找回历史版本的过程原理，请用户根据原理选择Git命令以完成在特定场景下需要的操作，不建议全流程直接复制使用。
当用户要查看某个Tag指向版本的代码时，可以将其检出到工作区。由于被检出的版本仅隶属于Tag，而不属于任何分支，因此该代码可以编辑，但是不能add、commit。用户可以基于工作区新建一条分支，在此分支上修改代码，并将此分支合入主干。具体的操作步骤如下所示。
1. 通过Tag检出历史版本。
   ```
   git checkout V2.0.0                 #将被Tag为 V2.0.0 的版本检出到工作区
   ```
   ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002251195613.png)
   
2. 基于当前的工作区新建一条分支并切换到其中。
   ```
   git switch -c  forFixV2.0.0         #新建一条名为 forFixV2.0.0 的分支，并切换到其中
   ```
   ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216155824.png)
   
3. （可选）如果修改了新建的分支的内容，需要将修改内容提交到该分支的版本库中。
   ```
   git add .                           #将修改添加到新分支的暂存区
   git commit -m "fix bug for V2.0.0"  #将修改内容存入该分支的版本库
   ```
   ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216315612.png "点击放大")
   
4. 切换到master分支，并将新建立的分支合入（本示例中为 forFixV2.0.0 分支）。
   ```
   git checkout master                #切换到master分支
   git merge forFixV2.0.0             #将基于历史版本的修改 合入到master分支
   ```
   ![](https://support.huaweicloud.com/usermanual-codeartsrepo/zh-cn_image_0000002216315592.png "点击放大")
   
 
