就像大多數的版本管理系統,Git具備在特定時間點加入標籤去註明其重要性的功能。一般而言,我們會使用這個功能去標記出發行版本(如V1.0等等)。這個小節中,你將會學到如何列出既有的標籤、建立新標籤以及各種不同標籤間的差異。
在Git中列出既有的標籤是非常簡單的。直接輸入git tag
:
$ git tag
v0.1
v1.3
這個指令將以字母順序列出標籤;所以這個順序並不代表其重要性。
你也可以用特定的字串規則去搜尋標籤。以Git本身的儲存庫為例,其中包含超過240個標籤。當你只對1.4.2感興趣時,你可以執行以下指令:
$ git tag -l 'v1.4.2.*'
v1.4.2.1
v1.4.2.2
v1.4.2.3
v1.4.2.4
Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。輕量級標籤就像是沒有更動的分支,實際上它僅是指到特定commit的指標。然而,含附註的標籤則是實際存在Git資料庫上的完整物件。它具備檢查碼、e-mail和日期,也包含標籤訊息,並可以被GNU Privacy Guard (GPG)簽署和驗證。一般而言,我們都建議使用含附註的標籤以便保留相關訊息;但如果只是臨時加註標籤或不需要保留其他訊息,就是使用輕量級標籤的時機。
建立一個含附註的標籤很簡單。最容易的方法是加入-a
到tag
指令上:
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag
v0.1
v1.3
v1.4
而-m
選項用來設定標籤訊息。如果你沒有設定該訊息,Git會啟動文字編輯器讓你輸入。
透過git show
可看到指定標籤的資料與對應的commit。
$ git show v1.4
tag v1.4
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 14:45:11 2009 -0800
my version 1.4
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sun Feb 8 19:02:46 2009 -0800
Merge branch 'experiment'
在列出commit資訊前,我們可以看到這個標籤的設定者資訊,下標籤時間與附註訊息。
假設你有私鑰(private key),你也可以用GPG簽署在標籤上。只要用-s
取代-a
:
$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon <schacon@gee-mail.com>"
1024-bit DSA key, ID F721C45A, created 2009-02-09
再對這個標籤執行git show
,你就能看到你的GPG簽章以經附在裡面:
$ git show v1.5
tag v1.5
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 15:22:20 2009 -0800
my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
=WryJ
-----END PGP SIGNATURE-----
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sun Feb 8 19:02:46 2009 -0800
Merge branch 'experiment'
稍後你會看到如何驗證已簽署的標籤。
另一種則是輕量級的標簽。基本上就是只保存commit檢查碼的文件。要建立這樣的標籤,不必下任何選項,直接設定標籤名稱即可。
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5
這樣一來,當執行git show
查看這個標籤時,你不會看到其他標籤資訊,只會顯示對應的commit:
$ git show v1.4-lw
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sun Feb 8 19:02:46 2009 -0800
Merge branch 'experiment'
想要驗證已簽署的標籤,需要使用git tag -v [tag-name]
。這個指令透過GPG去驗證簽章。而且在你的keyring中需要有簽署者的公鑰才能進行驗證:
$ git tag -v v1.4.2.1
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
GIT 1.4.2.1
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
gpg: aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
如果沒有簽署者的公鑰,則會看到下列訊息:
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.4.2.1'
你也可以對過去的commit上加入標籤。假設你的commit歷史如下:
$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
如果你之前忘了將"updated rakefile"這個commit加入v1.2標籤。仍然可在事後設定。要完成這個動作,你必須加入該次commit的檢查碼(或前幾碼即可)到以下指令:
$ git tag -a v1.2 9fceb02
你可以看到標籤已經補上:
$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5
$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 15:32:16 2009 -0800
version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date: Sun Apr 27 20:43:35 2008 -0700
updated rakefile
...
在預設的情況下,git push
指令並不會將標籤傳到遠端伺服器上。當建立新標籤後,你必須特別下指令才會將它推送到遠端儲存庫上。類似將分支推送到遠端的過程,透過git push origin [tagname]
指令。
$ git push origin v1.5
Counting objects: 50, done.
Compressing objects: 100% (38/38), done.
Writing objects: 100% (44/44), 4.56 KiB, done.
Total 44 (delta 18), reused 8 (delta 1)
To git@github.com:schacon/simplegit.git
* [new tag] v1.5 -> v1.5
如果你有很多標籤需要一次推送上去,你也可以加入--tags
選項到git push
指令中。這將會傳送所有尚未在遠端伺服器上的標籤。
$ git push origin --tags
Counting objects: 50, done.
Compressing objects: 100% (38/38), done.
Writing objects: 100% (44/44), 4.56 KiB, done.
Total 44 (delta 18), reused 8 (delta 1)
To git@github.com:schacon/simplegit.git
* [new tag] v0.1 -> v0.1
* [new tag] v1.2 -> v1.2
* [new tag] v1.4 -> v1.4
* [new tag] v1.4-lw -> v1.4-lw
* [new tag] v1.5 -> v1.5
現在,當其他使用者clone或pull你的儲存庫時,他們也同時會取得所有你的標籤。