[英]Git tag tags all the previous commits as well
目前,我正在嘗試在github上提供我的庫。 有兩個版本: 0.1
和0.2
。 我知道pip
可以通過git上的標簽找到軟件包的版本,因此我考慮過對其進行標簽。
當我做:
git add .
git commit -m "msg1"
git tag -a 0.1 -m "lib v0.1"
git push origin master --tag 0.1
第一次提交標記為0.1
但是,當我更改代碼中的某些內容時,我幾乎會做同樣的事情:
git add .
git commit -m "msg2"
git tag -a 0.2 -m "lib v0.2"
git push origin master --tag 0.2
最后一次提交被標記為0.2,但是第一次提交被標記為0.2和0.1。 難道我做錯了什么? 還是應該這樣?
@編輯。 這是我的git的樣子:
Releases
標簽:
基於github如何在其UI中顯示標簽,這只是一個誤解。 當git在提交上顯示標簽時,並不一定意味着該提交使用該版本進行了標簽。 要查看github中的實際標簽,可以單擊“發布”選項卡。
沒事的
GitHub試圖向GitHub用戶隱藏很多Git的復雜性。 我相信這是一個錯誤。 盡管眾所周知,Git對用戶不友好(例如,請參閱“我討厭Git的10件事”或xkcd#1597 ), 但確實有一些復雜性是必要的。 1
對於Git標簽,要意識到的是標簽,任何一個標簽都只是某些特定哈希ID的人類可讀名稱。 哈希ID是GitHub變灰並縮寫的幾乎像丑陋的數字一樣的東西,幾乎無法讀取。 在屏幕快照中,此處顯示的兩個是a89f1cc
和31a6a2d
。
這些哈希ID是Git對象的真實名稱,即Git本身用來查找對象內容的名稱。 這些哈希ID本身是通過對內容應用密碼哈希來產生的,因此哈希ID是鍵值數據庫的短(ish)密鑰:給定密鑰,保證該密鑰對於那些特定內容是唯一的, 2 Git可以查找值並獲取全部內容。 由於兩個哈希值不同,因此兩個對象也必然不同。 如果兩個對象相同,則兩個散列將相同。
對於帶注釋的標簽對象,實際上有必要加深一點:帶注釋的標簽的內容包括目標對象的哈希值。 這是最容易從命令行完成的-再次,GitHub隱藏了細節,而不是命令行很清晰:
git rev-parse a89f1cc^{}
例如,將查找對象a89f1cc
,檢查它是否是帶注釋的標記對象,如果是,則將其跟隨標記本身命名的其他任何對象。 如果a89f1cc
是其他類型的對象,則后綴^{}
不起作用。 我們也可以這樣寫:
git rev-parse a89f1cc^{commit}
它將找到a89f1cc
解析為的提交對象,或產生一個錯誤,在這種情況下,這就是我們想要的:這將為我們提供a89f1cc
本身的完整哈希ID(如果已經是提交),或者產生a89f1cc
解析為提交的哈希ID(如果它解析為提交),否則出錯。
對於使用系統的人來說,更實際的做法是給定兩個標簽名稱,您可以使用以下名稱 :
git rev-parse v0.1^{commit}
和:
git rev-parse v0.2^{commit}
查找標簽所指向的提交。 (某些shell可能需要在帽子^
和/或大括號{...}
字符周圍加一些引號;這取決於您是否使用bash,tcsh,PowerShell或其他任何方式。您可能需要稍微調整這些命令行命令讓您的外殼開心。)
將兩個標簽哈希值中的每個哈希值解析為提交,將告訴您哪個或兩個不同標簽名稱的提交。 可以為一個提交提供多個標簽,但是您沒有這樣做,因此您將獲得兩個不同的提交哈希。 這些提交是pip install
將檢出,構建和安裝的提交。
1 艾伯特·愛因斯坦(Albert Einstein)通常被解釋為:“ 一切都應該盡可能簡單,但不要簡單”,盡管Wikiquote說他實際上是寫的。幾乎可以否認的是,所有理論的最高目標是使不可還原的基本元素既簡單又簡單。盡可能少地付出,而不必屈服於單一經驗數據。
2這有點誇大其詞,具體取決於您的Git版本。 有關詳細信息,請參見git中的哈希沖突 。
如果您只是要安裝,以上就是您所關心的。 但是,作為一個使用Git本身的人,還有另一件事需要學習。
我們在上面看到,標簽名稱通過git rev-parse
(在適當的時候,大多數Git命令在內部執行) git rev-parse
為哈希ID。 但是對於像master
或develop
這樣的分支名稱 ,也是如此( 大部分情況下都是如此)。 我們可以運行:
$ git rev-parse v2.16.0
e1c2c6b098dfb717a4a6ff7f3894d57343210a41
並獲得像這樣的哈希ID,但是我們也可以運行:
$ git rev-parse master
ccdcbd54c4475c2238b310f7113ab3075b5abc9c
並獲取哈希ID。 該哈希ID是名稱master
指向的(一個,一個!)提交。 Git的所有引用都是如此:分支名稱,標簽名稱,遠程跟蹤名稱(如origin/master
等等)都是引用的形式,在Git中, 每個引用都轉換為一(1)個哈希ID。
分支名稱的特殊之處在於它們會隨着時間而變化 。 他們現在存儲一個哈希ID,然后在您運行git commit
,某些分支名稱將存儲一個新的不同的哈希ID。 這其實是分支機構如何成長:你告訴Git的,你想成為的一些分支,通過運行,如:
git checkout master
之后git status
on branch master
。 在分支上的意思是git commit
將為您更改該分支的名稱:Git將進行一個新的提交,這將獲得一些看起來隨機的新哈希ID,然后Git將該新提交的哈希ID存儲到master
的名字。
潛在的機制是特殊名稱HEAD
(大寫字母,盡管在進行大小寫折疊的Windows和Mac系統上,您通常可以使用全小寫)。 Git 將單詞HEAD
附加到分支名稱 ,以便記住您要求Git處於哪個分支。
如果分支名稱只有一個大寫字母,則可以這樣繪制:
A <-B <-C <-- master (HEAD)
這意味着HEAD
被附接到master
,並且名稱master
點提交 C
-它包含用於提交的散列ID C
。 提交C
本身包含早期提交B
的哈希ID,而提交B
包含提交A
的哈希ID。
在我們的例子中,我們的存儲庫很小:它只有這三個提交。 提交A
沒有更早的提交(Git稱為根提交) ,因此它沒有指向任何地方。 這顯示了Git的工作原理:它使用名稱 master
查找當前提交C
的哈希ID,然后使用提交C
的內容查找C
的父提交B
B
的內容讓Git找到B
的父A
,而A
沒有父,因此現在停止操作:Git顯示您先提交C
,然后是B
,然后是A
,然后停止。
換句話說,吉特倒退了 。
當您進行新的提交D
,Git通過記錄所有代碼的快照,記錄早期提交C
的實際哈希ID,然后寫出提交並獲取其實際哈希ID(無論是什么)來創建此提交。 然后,Git使用HEAD
知道將新的哈希ID寫入master
,得到:
A <-B <-C <-D <-- master (HEAD)
現在master
名稱(指向)提交D
同樣,這就是分支通常如何移動和增長的方式。 分支名稱 master
和標記名稱 v0.1
之間的區別在於, 分支名稱 應該移動 ( 假設隨時間變化,以命名該分支的最后一次提交),但是標記名稱不會移動。 一旦分配了標記名稱以指向某個特定的提交,它便會停留在該位置:它將一直指向該提交。
從commit到commit的鏈接形成一個graph ,正是這個commit graph確實將Git粘合在一起。 GitHub嘗試向您隱藏提交圖。 因為Git主要是關於圖形的-只是文件而已-這是一個可怕的損害。 了解提交圖對於使用Git至關重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.