Git應用詳解第八講:Git標籤、別名與Git gc

第八講:Git標籤、別名與Git gc

前言
這一節主要介紹Git標籤、別名與Git的垃圾回收機制。git

1、
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官方文檔對兩種標籤的說明,大意是:帶註釋的標籤用於發佈,而輕量級標籤則用於私人或臨時對象。框架

「何時打標籤呢?」ide

「版本發佈」:通常master分支都會做爲項目的發佈分支,當項目開發到了一個成熟的階段,準備在master分支進行發佈時。通常都會在master分支的當前提交上打上一個相似"v1.2"的標籤;學習

好比Vue框架:測試

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418125541646
能夠看到有許多標籤,而且能夠在releases選項中查看標籤和發佈版本:
Git應用詳解第八講:Git標籤、別名與Git gc優化

image-20200418125721571
「版本管理」:能夠經過標籤的形式記錄項目某一階段的狀態,方便管理;

好比管理學習微信小程序時每一個知識點的代碼:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418165957032
「查看標籤文件」
以下圖所示,分別給master分支的提交mas2添加一個輕量級標籤v1.0和一個帶有附註的標籤v2.0:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418122516160

git dog爲git log --all --decorate --oneline --graph的別名,後面會講解;


隨後,查看存儲標籤文件的.git/refs/tags目錄:
Git應用詳解第八講:Git標籤、別名與Git gc

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值;

這就是輕量級標籤與帶有附註標籤的區別。不過這兩個標籤仍然會指向同一次提交,以下圖所示:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418124847587
2.建立標籤
git tag <tag_name>
建立一個輕量級標籤:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200311143441005
git tag -a <tag_name> -m '註釋'
建立一個帶有附註的標籤:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200311143555121
3.查看標籤
git tag
顯示添加的全部標籤:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418140044357
也能夠添加--list參數:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418140101235
以下圖所示:切換了分支tag仍然存在,說明tag與分支並無關係,它標識的是某次特定的提交:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418140210619
git show <tag_name>
如圖所示,在master分支上進行兩次提交,每次爲文件test.txt添加一行內容而且打上標籤。其中v1.0爲輕量級標籤,v2.0爲帶有附註的標籤:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418164206660
隨後,使用git show查看標籤的內容:
Git應用詳解第八講:Git標籤、別名與Git gc
「輕量級標籤」:

image-20200418164502188
如圖所示,該指令會顯示標籤v1.0所指向的提交;而且,會輸出標籤指向提交與上一次提交的比較結果;因爲標籤v1.0指向的提交爲master分支的第一次提交,因此上一次提交爲null。所以比較結果顯示:相比於上一次提交,標籤指向的提交1st在文件test.txt中新增了一行1st;

「帶註釋的標籤」:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418165301312
相比於輕量級標籤,帶附註的標籤是一個對象,能夠存儲附註和打標籤的人和時間等信息,因此顯示的信息多一些;從圖中的比較結果可知,相比於上一次提交1st,標籤v2.0指向的提交2nd爲文件test.txt新增了一行2nd;

4.查找標籤
git tag -l <tag_name>
該方式支持正則表達式查找;

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418140732354
如上圖所示:

v表示搜索全部以v開頭的標籤;
?2
表示搜索任意開頭,但包含2的標籤;
5.將標籤推送到遠程
要將標籤推送到遠程倉庫,首先要創建本地倉庫與遠程倉庫的聯繫,好比能夠採用:

git push -u origin master

創建本地master分支與遠程master分支的聯繫,並進行一次推送:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418143423585
git push origin <tag_name>
這種方法能夠推送指定的本地標籤到遠程倉庫,例如將本地master分支上的標籤v1.0推送到遠程倉庫:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418143541273
執行上述指令後,對應的遠程倉庫gitTest中就會出現相應的tag信息了:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418143927912
也能夠在releases選項中,查看tag和Releases信息:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418144230515
Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418144207107
「也能夠同時推送多個本地標籤到遠程倉庫」:

git push origin  v2.0 v3.0

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418144612359
以上的命令都是簡寫形式,「完整寫法爲」:

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

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418144755135
git push origin --tag
該方法能夠一次性推送全部的本地標籤到遠程倉庫:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418144952994
也能夠採用簡寫命令:

//下面的tag能夠寫成tags,效果同樣
git push --tag

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418145049074
6.刪除遠程標籤
固然,咱們能夠直接在遠程倉庫上刪除遠程標籤。可是,最好的方式仍是採用命令行進行刪除。刪除遠程標籤的方法與刪除遠程分支的方法很是相似,一樣有兩種方法:

git push origin :<tag_name>
這種方法至關於推送一個空的標籤到遠程倉庫,由此達到刪除的效果。好比刪除遠程倉庫中的標籤v3.0:

git push origin :v3.0

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418154504982
這樣遠程倉庫中的標籤V3.0就被刪除了:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418154554319
可是本地倉庫中對應的標籤V3.0並無被刪除:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418154631370
上述指令爲簡寫,「完整寫法以下」:

git push origin :refs/tags/v3.0

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418154906969
git push origin --delete <tag_name>
該方法採用了更加語義化的參數--delete,實現遠程標籤的刪除:

git push origin --delete v2.0

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418155134748
一樣成功地刪除了遠程倉庫中的標籤v2.0:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418155216230
可是,本地的標籤v2.0也沒有被刪除:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418155311429
採用下列的完整寫法,效果是同樣的:

git push origin --delete tag v2.0

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418155513090

不難發現,刪除「遠程分支」和「遠程標籤」的方法是「同樣」的。


7.刪除本地標籤
git tag -d <tag_name>
如經過如下命令刪除標籤v3.0:

git tag -d v3.0

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418155616562
8.切換標籤
git checkout <tag_name>
如圖所示,在master分支上進行了三次提交,而且添加了相應的標籤:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418161353146
當咱們經過checkout命令切換到標籤v2.0時:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418161526176
可見,會出現遊離的提交。此時查看各分支狀態:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418161655468
如上圖所示,當前處於標籤v2.0指向的提交,而且切換標籤的過程當中改變了HEAD指針的指向。可是,並無改變分支master的指向。過程以下圖所示:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418162458123
也就是說,切換標籤與使用reset進行版本回退十分類似。只不過切換標籤只改變了HEAD指針的指向,會形成遊離的提交。如有須要能夠建立一個新分支進行保存。

9.拉取標籤
在下圖所示的狀況中,本地倉庫mygit與遠程倉庫有公共的提交歷史(同源),而且不發生合併衝突的狀況下(具體可參考Git應用詳解第六講:Git協做與Git pull常見問題):
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418160517111
能夠直接經過git pull將遠程倉庫的標籤拉取下來,並建立本地倉庫中沒有的標籤:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418160737829
2、
Git
別名

1.設置git命令別名
git config <做用域> alias.<別名> '<命令>'
別名就是一個替代,使用一個簡短的字符串來代替經常使用的長命令。好比能夠經過以下命令,使用別名bra來替代branch命令:

git config --global alias.bra branch

Git應用詳解第八講:Git標籤、別名與Git gc

image-20200417184645237
當命令較爲簡短時,能夠省略命令兩邊的單引號:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200417184803691
在上述命令中:

--global表示設置的別名做用域爲系統用戶,即該用戶對全部的git倉庫均可以使用這個別名;其他還有倉庫做用域--loacl,系統做用域--system;

alias.br表示更改別名爲br;

再日後的branch表示須要起別名的命令,能夠是帶參數的長命令,此時不能省略命令兩邊的單引號:

git config --global alias.dog 'log --all --decorate --oneline --graph'
Git應用詳解第八講:Git標籤、別名與Git gc
image-20200413171109680
因爲上面配置的別名做用域爲系統用戶,該配置會寫入gitconfig配置文件。打開該文件能夠看到寫入的「別名配置」:


「補充」:使用vi ~/.gitconfig能夠直接打開gitconfig這個文件(記得加點),不管當前所處的路徑是什麼;


Git應用詳解第八講:Git標籤、別名與Git gc
image-20200417185537264
也就是說能夠直接經過修改gitconfig文件的alias選項來設置別名,可是「不建議」。

這樣,經過別名就能夠簡化一些經常使用的命令了,好比git status、git checkout等:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200417185854925
2.設置外部命令別名
像gitk這樣的外部命令,是沒有git前綴的。設置別名的方法與設置git提供的命令有所不一樣,要按照以下格式設置:

git config <做用域> alias.<別名> '<!外部命令>'
感嘆號表示這是一個外部命令;
注意要加上單引號,不用加git前綴;
好比在系統用戶做用域下,將git ui設置爲gitk的別名:

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

設置完成後,該配置會被寫入系統用戶的配置文件gitconfig中:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200417190632295
隨後直接使用git ui便能打開gitk界面:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200417190558949
「補充」:設置了別名後,原來的命令仍然有效。

3、垃圾回收:
Git gc

所謂gc就是垃圾回收機制,實際使用較少;它的做用是「清理沒必要要的文件並優化本地存儲庫」。

爲了演示它的做用,設置如下測試環境:

首先,在本地倉庫mygit建立master和dev兩個分支,並將它們推送到遠程倉庫:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418105755292
而後,給本地倉庫mygit添加一個輕量級標籤v1.0和一個帶有附註的標籤v2.0:

Git應用詳解第八講:Git標籤、別名與Git gc
image-20200418110041381
此時.git/refs目錄下的各文件以下所示:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418110228125
heads目錄存儲的是本地分支信息,remote目錄存儲的是遠程分支信息,tags目錄存儲的是標籤信息,符合預期。

隨後,執行git gc命令:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418110332080
再次查看.git/refs目錄:
Git應用詳解第八講:Git標籤、別名與Git gc

image-20200418110544449
能夠看到refs目錄及其子目錄下的文件消失了,可是.git目錄下多了一個packed-refs文件。事實上,refs目錄下的文件不是消失了,而是被打包到了packed-refs文件中。打開packed-refs文件:
Git應用詳解第八講:Git標籤、別名與Git gc

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纔會被打包。

相關文章
相關標籤/搜索