2008-12-21 95 views
107

我通過一堆問題來了解簡單的源代碼控制工具,而git看起來像是一個合理的選擇。我已經開始運行,迄今爲止效果很好。我喜歡CVS的一個方面是版本號的自動增量。

我知道這在分佈式存儲庫中的意義不大,但作爲開發人員我想要/需要這樣的東西。讓我解釋一下爲什麼:

我使用Emacs。我會定期查看第三方軟件包的lisp源文件的新版本。假設我有一個文件foo.el,根據標題是1.3版;如果我查看最新版本並且看到它是1.143或2.6或者其他什麼,我知道我遠遠落後。相反,如果我看到一對40個字符的哈希,我不知道後面哪個或後面有多少。如果我必須手動檢查ChangeLogs才能瞭解我是如何過時的,我絕對會恨它。作爲一名開發人員,我想將這種禮貌擴展到使用我的輸出的人(也許我在開玩笑說任何人都在,但讓我們暫且擱置一會兒)。我不希望每次都記住自己增加該死的數字,或者時間戳或類似的東西。這是一個真正的PITA,我從經驗中知道。

那麼我有什麼替代方案?如果我無法獲得$ Id:$等價物,我還能如何提供我所尋找的?謝謝您的幫助!

編輯:我應該提到,我的期望是,最終用戶將不會安裝git,即使他們這樣做,也不會有本地存儲庫(實際上,我希望不會以這種方式提供)。感謝迄今爲止的答案!

回答

62

的SHA只是一個的版本(雖然規範的)表示。該git describe命令提供了其他人,這樣做非常好。

例如,當我在java memcached client源我主分支運行git describe,我得到這個:

2.2-16-gc0cd61a 

,上面寫着兩個重要的事情:在

  1. 已經有確切16個提交此樹自2.2
  2. 確切源樹可以顯示在任何其他克隆上。

比方說,例如,您打包了一個version文件與來源(甚至重寫所有發佈內容)以顯示該數字。假設打包版本爲2.2-12-g6c4ae7a(不是發行版,而是有效版本)。

現在,您可以看到究竟有多遠後面你(4次提交),你可以清楚地看到這4個提交:

# The RHS of the .. can be origin/master or empty, or whatever you want. 
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a 
c0cd61a Dustin Sallings More tries to get a timeout. 
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui 
fb326d5 Dustin Sallings Added a test for bug 35. 
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations. 
23

不知道這將永遠在Git中。要quote Linus

「關鍵字替換的整個概念是隻是完全愚蠢這是 容易做到。‘外面’的實際內容的跟蹤,如果你想 有它做發行樹木焦油球時等等。」

這是很容易查看日誌,雖然 - 如果您要跟蹤foo.el的穩定分支,你可以看到什麼新的提交是穩定分支的日誌不在本地副本。如果您想模擬CVS的內部版本號,則可以比較上次提交的時間戳。

編輯:你應該爲此編寫或使用別人的腳本,當然這不是手動完成的。

+23

是啊,我也讀到了關鍵字擴展電子郵件的那一長串的一部分。 Linus的態度幾乎足以讓我徹底擺脫混亂。 – 2008-12-21 15:52:27

+15

是的,有時他缺乏禮貌,但他通常是正確的,他肯定是在關鍵詞擴展的話題。 – Bombe 2008-12-21 18:12:25

+11

與理查德斯托曼相比,他很開朗。 – 2013-04-26 01:04:43

3

如果我理解正確,基本上,您想知道自上次更新以來在給定文件上發生了多少次提交。

首先獲得遠程起源的變化,但不要將其合併到master分支:

% git fetch 

然後得到一個日誌已經發生在一個給定的文件你master分支之間的變化遠程origin/master

% git log master..origin/master foo.el 

這樣,您在遠程倉庫發生自上次合併origin/master到您的master所有提交的日誌信息。

如果您只是想要對更改進行計數,請將其管理至wc。說,像這樣的:

% git rev-list master..origin/master foo.el | wc -l 
+0

所以,不要使用日誌:git rev-list master..origin/master | wc -l – Dustin 2008-12-22 03:55:47

+0

更新了答案。 – Otto 2008-12-23 01:51:04

4

如果你只是想人們能夠得到一個想法多遠過時他們的,混帳可以在幾個比較簡單的方法告知那他們。例如,他們比較他們幹線上的最後提交日期和你的幹線。他們可以使用git cherry來查看在你的箱子裏發生了多少沒有出現在他們身上的提交。

如果這是你想要爲這,我會尋找一種方式來提供它沒有版本號。

而且,除非你確定他們希望我不會刻意延長禮貌的人。 :)

8

與git存儲庫完成的事情是使用tag對象。這可用於使用任何類型的字符串標記提交,並可用於標記版本。您可以看到與git tag命令,該命令將返回所有的標籤回購該標籤。

很容易檢查出的標籤。例如,如果有v1.1您可以檢查標籤出一個分支這樣的標籤:

git checkout -b v1.1 

由於這是一個頂級對象,你會看到整個歷史上犯下,以及是能夠運行差異,進行更改和合並。

不僅如此,而且標籤仍然存在,即使它所在的分支已被刪除而未被合併回主線。

8

如果有$關鍵字$對您來說至關重要,那麼也許您可以嘗試查看Mercurial而不是?它有一個hgkeyword擴展實現你想要的。無論如何,Mercurial作爲一個DVCS很有趣。

20

正如我已經寫before

自動地生成,顯示一個明智的版本號是不可能的DSCM工具,如巴扎做的,因爲發展的每個人的線可與所有其他不同的ID標籤。所以有人能指文件的版本「1.41」,但你該文件的版本「1.41」是不同的。

基本上,$ Id $對Bazaar,Git和其他分佈式源代碼管理工具沒有任何意義。

0

既然你用emacs,你可能會幸運:)

我偶然發現了這個問題,也是巧合,前幾天我收到了Lively,這是一個emacs軟件包,它允許在您的文檔中生動地生成emacs文件。我沒有試圖說實話,但是在閱讀本文時,我想到了這一點。

49

現在在Git中支持$ Id:$。要啓用它的文件自述文件您可以將「README ident」放入.gitattributes。支持文件名上的通配符。詳情請參閱man gitattributes

30

這不是OP的無理要求。

我用例是:

  1. 我使用git我個人的代碼,因此沒有與他人合作。
  2. 我將系統Bash腳本保存在那裏,當它們準備就緒時,腳本可能會進入/ usr/local/bin。

我使用3個具有相同git回購的獨立機器。很高興知道我目前在/ usr/local/bin目錄下的文件有哪些「版本」,而無需執行手動「diff -u

對於那些負面的人,請記住還有其他的用法 - 。那裏的情況並不是所有人都使用的git與在混帳回購協議是他們的「最後」位置的文件協同工作

但無論如何,我做的方式是創建一個屬性在回購這樣的文件:

cat .git/info/attributes 
# see man gitattributes 
*.sh ident 
*.pl ident 
*.cgi ident 

然後把$ Id $放在文件的某處(我喜歡把它放在shebang之後)

提交。請注意,這不會像我預期的那樣自動執行解釋。你必須重新創建文件,例如。

git commit foo.sh 
rm foo.sh 
git co foo.sh 

,然後你會看到的擴展,如:

$ head foo.sh 
#!/bin/sh 

# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $ 

How do I enable ident string for Git repos?

7

一些好的信息,我有同樣的問題。需要有一個比散列字符串更簡單的版本,並且可供使用該工具的人員使用,而無需連接到存儲庫。

我做了一個git pre-commit hook,並將腳本更改爲能夠自動更新自身。

我基於完成的提交數量的版本。這是一個輕微的競爭條件,因爲兩個人可以同時提交,並且都認爲他們提交的版本號相同,但是我們在這個項目中沒有很多開發人員。

礦是紅寶石,但它不是非常複雜的代碼。紅寶石腳本有:

MYVERSION = '1.090' 
## Call script to do updateVersion from .git/hooks/pre-commit 
def updateVersion 
    # We add 1 because the next commit is probably one more - though this is a race 
    commits = %x[git log #{$0} | grep '^commit ' | wc -l].to_i + 1 
    vers = "1.%0.3d" % commits 

    t = File.read($0) 
    t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'") 
    bak = $0+'.bak' 
    File.open(bak,'w') { |f| f.puts t } 
    perm = File.stat($0).mode & 0xfff 
    File.rename(bak,$0) 
    File.chmod(perm,$0) 
    exit 
end 

然後我有,對於工具調用updateVersion一個命令行選項(-updateVersion)。

最後,我轉到git頭並在.git/hooks/pre-commit中創建一個可執行腳本。

腳本只是改變到GIT目錄的頭部,並與-updateVersion

每次我檢查在叫我的劇本,MYVERSION變量是基於什麼提交的數目將被更新。

1

我同意那些認爲令牌替換屬於構建工具而不是版本控制工具的人。

您應該使用一些自動發佈工具在發佈標籤時設置源代碼中的版本ID。

2

對於單個文件項目,RCS ID很好,但是對於任何其他的$ Id $都沒有提及該項目(除非您強制將虛擬簽入放入虛擬版本文件中)。

還有一個人可能會感興趣如何在每個文件級別或提交級別獲取$ Author $,$ Date $,$ Revision $,$ RCSfile $等等的對應值(如何將它們放在某處關鍵字是另一個問題)。我對這些沒有答案,但看到更新這些的要求,特別是當文件(現在在Git中)起源於RCS兼容系統(CVS)時。

如果源代碼與任何Git存儲庫分開發布(這也是我所做的),這些關鍵字可能會很有趣。我的解決方案是這樣的: 每個項目都有一個自己的目錄,並且在項目根目錄中,我有一個名爲.version的文本文件,其內容描述了當前版本(導出源時將使用的名稱)。

雖然工作的下一個版本一個腳本提取.version數量,一些Git版本描述符(如git describe)和.build單調版本號(加主機和日期)被鏈接到一個自動生成的源文件最終的程序,所以你可以從什麼來源以及何時建立。

我開發單獨的分支新的功能,我做的第一件事就是添加n(對於「下一個」)在.version字符串(多個分支機構同根原將使用相同的臨時.version號)。在發佈之前,我決定合併哪些分支(希望所有分支都具有相同的.version)。在提交合並之前,我將.version更新爲下一個數字(主要或次要更新,具體取決於合併的功能)。

0

我也來自SCCS,RCS和CVS(%W%%G%%U%)。

我有類似的挑戰。我想知道運行它的任何系統上的代碼片段的版本。系統可能連接到或不連接到任何網絡。系統可能安裝了git,也可能沒有。系統可能會或可能不會安裝github存儲庫。我想爲幾種類型的代碼(.sh,.go,.yml,.xml等)提供相同的解決方案。我希望任何不瞭解Git或GitHub的人都能夠回答這個問題;你正在運行什麼版本?

所以,我寫了一些我稱之爲幾個git命令的包裝器。我用它來標記具有版本號和一些信息的文件。它解決了我的挑戰。它可能會幫助你。

https://github.com/BradleyA/markit

git clone https://github.com/BradleyA/markit 
cd markit