我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
当前回答
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在错误跟踪器或问题跟踪器中进行的。标签倾向于为版本颠簸保留,为维护分支保留分支点(用于旧版本)。
其他回答
git describe命令创建一个更容易读懂的名称,用于引用特定的提交。例如,从文档中:
和像少年犯一样的东西。git当前树,我得到: [torvalds@g5 git]$ git描述父 v1.0.4-14-g2414721 例如,我的“父”分支的当前头基于v1.0.4,但由于它在此之上有一些提交,describe在最后添加了额外提交的数量(“14”)和提交本身的缩写对象名称(“2414721”)。
只要您使用合理命名的标记标记特定的版本,就可以认为这大致相当于SVN的“修订号”。
我编写了一些PowerShell实用程序,用于从Git中检索版本信息并简化标记
函数:Get-LastVersion, Get-Revision, Get-NextMajorVersion, Get-NextMinorVersion, TagNextMajorVersion, TagNextMinorVersion:
# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
$lastTagCommit = git rev-list --tags --max-count=1
$lastTag = git describe --tags $lastTagCommit
$tagPrefix = "v"
$versionString = $lastTag -replace "$tagPrefix", ""
Write-Host -NoNewline "last tagged commit "
Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
Write-Host -NoNewline " revision "
Write-Host -ForegroundColor "yellow" "$lastTagCommit"
[reflection.assembly]::LoadWithPartialName("System.Version")
$version = New-Object System.Version($versionString)
return $version;
}
# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
$lastTagCommit = git rev-list HEAD
$revs = git rev-list $lastTagCommit | Measure-Object -Line
return $revs.Lines
}
# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
$version = Get-LastVersion;
[reflection.assembly]::LoadWithPartialName("System.Version")
[int] $major = $version.Major+1;
$rev = Get-Revision
$nextMajor = New-Object System.Version($major, 0, $rev);
return $nextMajor;
}
# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
$version = Get-LastVersion;
[reflection.assembly]::LoadWithPartialName("System.Version")
[int] $minor = $version.Minor+1;
$rev = Get-Revision
$next = New-Object System.Version($version.Major, $minor, $rev);
return $next;
}
# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
$version = Get-NextMinorVersion;
$tagName = "v{0}" -f "$version".Trim();
Write-Host -NoNewline "Tagging next minor version to ";
Write-Host -ForegroundColor DarkYellow "$tagName";
git tag -a $tagName -m $tagMessage
}
# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
$version = Get-NextMajorVersion;
$tagName = "v{0}" -f "$version".Trim();
Write-Host -NoNewline "Tagging next majo version to ";
Write-Host -ForegroundColor DarkYellow "$tagName";
git tag -a $tagName -m $tagMessage
}
一个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中获取版本和修订:
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-rev-label
以master-c73-gabc6bec之类的格式给出有关Git存储库修订的信息。 可以填充模板字符串或文件与环境变量和信息从Git。 用于提供关于程序版本的信息:分支,标记,提交散列, 提交计数,脏状态,日期和时间。最有用的事情之一是计算 提交,不考虑合并的分支—只考虑第一个父分支。