我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
当前回答
这是我在基于其他解决方案的makefile中所做的。注意,这不仅为代码提供了一个修订号,还附加了允许您重新创建版本的散列。
# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID
其他回答
对于有Ant构建流程的人,您可以通过以下目标在git上生成项目的版本号:
<target name="generate-version">
<exec executable="git" outputproperty="version.revisions">
<arg value="log"/>
<arg value="--oneline"/>
</exec>
<resourcecount property="version.revision" count="0" when="eq">
<tokens>
<concat>
<filterchain>
<tokenfilter>
<stringtokenizer delims="\r" />
</tokenfilter>
</filterchain>
<propertyresource name="version.revisions" />
</concat>
</tokens>
</resourcecount>
<echo>Revision : ${version.revision}</echo>
<exec executable="git" outputproperty="version.hash">
<arg value="rev-parse"/>
<arg value="--short"/>
<arg value="HEAD"/>
</exec>
<echo>Hash : ${version.hash}</echo>
<exec executable="git" outputproperty="version.branch">
<arg value="rev-parse"/>
<arg value="--abbrev-ref"/>
<arg value="HEAD"/>
</exec>
<echo>Branch : ${version.branch}</echo>
<exec executable="git" outputproperty="version.diff">
<arg value="diff"/>
</exec>
<condition property="version.dirty" value="" else="-dirty">
<equals arg1="${version.diff}" arg2=""/>
</condition>
<tstamp>
<format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
</tstamp>
<echo>Date : ${version.date}</echo>
<property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />
<echo>Version : ${version}</echo>
<echo file="version.properties" append="false">version = ${version}</echo>
</target>
结果如下所示:
generate-version:
[echo] Generate version
[echo] Revision : 47
[echo] Hash : 2af0b99
[echo] Branch : master
[echo] Date : 2015-04-20.15:04:03
[echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03
当生成版本号时有文件未提交时,此处会出现脏标志。因为通常,当构建/打包应用程序时,每个代码修改都必须在存储库中。
git describe命令创建一个更容易读懂的名称,用于引用特定的提交。例如,从文档中:
和像少年犯一样的东西。git当前树,我得到: [torvalds@g5 git]$ git描述父 v1.0.4-14-g2414721 例如,我的“父”分支的当前头基于v1.0.4,但由于它在此之上有一些提交,describe在最后添加了额外提交的数量(“14”)和提交本身的缩写对象名称(“2414721”)。
只要您使用合理命名的标记标记特定的版本,就可以认为这大致相当于SVN的“修订号”。
我们使用这个命令从git中获取版本和修订:
git describe --always --tags --dirty
它返回
当没有使用标记时提交哈希作为修订(例如gcc7b71f) 当标签上的标签名称为版本时(例如v2.1.0,用于版本) 标签名称,自上一个标签以来的修订号,以及在标签之后提交哈希(例如v5.3.0-88-gcc7b71f) 如果工作树有局部修改(例如v5.3.0-88-gcc7b71f-dirty),则与上述相同,加上“dirty”标签。
参见:https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt
如果你感兴趣,我在这里的格式下从git信息自动管理版本号
<major>.<minor>.<patch>-b<build>
其中build是提交的总数。您将在Makefile中看到有趣的代码。下面是相关部分访问不同部分的版本号:
LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"
VERSION = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION = $(shell git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits
BUILD = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")
#REVISION = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)
Git没有与subversion相同的版本号概念。相反,使用提交生成的每个给定快照都被标记为SHA1校验和。为什么?在分布式版本控制系统中运行revno有几个问题:
首先,由于开发根本不是线性的,数字的附加作为一个问题很难以一种满足程序员需求的方式解决。试图通过添加一个数字来解决这个问题,当这个数字没有像您期望的那样表现时,可能很快就会出现问题。
第二,修订号可以在不同的机器上生成。这使得数字的同步变得更加困难——特别是因为连接是单向的;您甚至可能无法访问拥有存储库的所有计算机。
第三,在git中,在某种程度上是由现在已经不存在的OpenCM系统首创的,提交的身份(提交是什么)等同于它的名称(SHA id)。这种命名=身份的概念非常强烈。当你手上有一个提交名称时,它也会以一种不可伪造的方式标识提交。这反过来又让您可以使用git fsck命令检查所有提交到第一个初始提交的文件是否损坏。
Now, since we have a DAG (Directed Acyclic Graph) of revisions and these constitute the current tree, we need some tools to solve your problem: How do we discriminate different versions. First, you can omit part of the hash if a given prefix, 1516bd say, uniquely identifies your commit. But this is also rather contrived. Instead, the trick is to use tags and or branches. A tag or branch is akin to a "yellow stick it note" you attach to a given commit SHA1-id. Tags are, in essence, meant to be non-moving whereas a branch will move when new commits are made to its HEAD. There are ways to refer to a commit around a tag or branch, see the man page of git-rev-parse.
通常,如果您需要处理特定的代码段,则该代码段正在进行更改,因此应该是具有特定主题名称的分支。创建大量的分支(每个程序员20-30个分支也不是没听说过,还有4-5个发布给其他人工作)是有效git的诀窍。每一项工作都应该作为自己的分支开始,然后在测试时被合并。未发布的分支可以完全重写,这部分破坏历史的部分是git的力量。
当改变被接受为主人时,它就有些冻结了,变成了考古学。在这一点上,您可以标记它,但更多情况下,对特定提交的引用是通过sha1 sum在错误跟踪器或问题跟踪器中进行的。标签倾向于为版本颠簸保留,为维护分支保留分支点(用于旧版本)。