我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。

假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。


当前回答

一个Bash函数:

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

输出如下所示

$ git_rev
2:0f8e14e:20130220

这是

commit_count:last_abbrev_commit:date_YYmmdd

其他回答

如果你感兴趣,我在这里的格式下从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)

这是我在基于其他解决方案的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

不管对你来说是好消息还是坏消息,哈希值就是修订号。当我从SVN切换到git时,我也遇到了这个问题。

你可以在git中使用“tagging”将某个修订标记为特定版本的“release”,这样就可以方便地引用该修订。看看这篇博客文章。

要理解的关键是git不能有修订号——想想去中心化的本质。如果用户A和B都提交到他们的本地存储库,git如何合理地分配一个连续的修订号?在他们相互推动/拉动对方的变化之前,A对B一无所知。

另一件需要考虑的事情是用于修复错误的分支的简化分支:

从一个版本开始:3.0.8。然后,在释放之后,这样做:

git branch bugfixes308

这将为错误修复创建一个分支。检查分支:

git checkout bugfixes308

现在进行任何您想要的错误修复更改。

git commit -a

提交它们,然后切换回主分支:

git checkout master

然后从另一个分支中导入这些更改:

git merge bugfixes308

这样,您就有了一个单独的特定于发行版的错误修复分支,但是您仍然将错误修复更改拉到您的主开发主干中。

我们使用这个命令从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(在我的例子中是1.8.3.4)并且不使用分支,你可以做到:

$ git rev-list --count HEAD
68

但这有各种各样的问题,可能不容易重现,或者在需要时不容易回到提交散列。所以尽量避免,或者只把它作为一个暗示。