簡體   English   中英

Git標簽也標記所有先前的提交

[英]Git tag tags all the previous commits as well

目前,我正在嘗試在github上提供我的庫。 有兩個版本: 0.10.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中的實際標簽,可以單擊“發布”選項卡。

TL; DR

沒事的

GitHub試圖向GitHub用戶隱藏很多Git的復雜性。 我相信這是一個錯誤。 盡管眾所周知,Git對用戶不友好(例如,請參閱“我討厭Git的10件事”xkcd#1597 ), 確實有一些復雜性是必要的。 1

對於Git標簽,要意識到的是標簽,任何一個標簽都只是某些特定哈希ID的人類可讀名稱。 哈希ID是GitHub變灰並縮寫的幾乎像丑陋的數字一樣的東西,幾乎無法讀取。 在屏幕快照中,此處顯示的兩個是a89f1cc31a6a2d

這些哈希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用戶,還需要了解更多信息:標簽vs分支,以及提交圖

如果您只是要安裝,以上就是您所關心的。 但是,作為一個使用Git本身的人,還有另一件事需要學習。

我們在上面看到,標簽名稱通過git rev-parse (在適當的時候,大多數Git命令在內部執行) git rev-parse為哈希ID。 但是對於像masterdevelop這樣的分支名稱 ,也是如此( 大部分情況下都是如此)。 我們可以運行:

$ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM