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

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


当前回答

考虑使用

git-rev-label

以master-c73-gabc6bec之类的格式给出有关Git存储库修订的信息。 可以填充模板字符串或文件与环境变量和信息从Git。 用于提供关于程序版本的信息:分支,标记,提交散列, 提交计数,脏状态,日期和时间。最有用的事情之一是计算 提交,不考虑合并的分支—只考虑第一个父分支。

其他回答

git describe命令创建一个更容易读懂的名称,用于引用特定的提交。例如,从文档中:

和像少年犯一样的东西。git当前树,我得到: [torvalds@g5 git]$ git描述父 v1.0.4-14-g2414721 例如,我的“父”分支的当前头基于v1.0.4,但由于它在此之上有一些提交,describe在最后添加了额外提交的数量(“14”)和提交本身的缩写对象名称(“2414721”)。

只要您使用合理命名的标记标记特定的版本,就可以认为这大致相当于SVN的“修订号”。

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在错误跟踪器或问题跟踪器中进行的。标签倾向于为版本颠簸保留,为维护分支保留分支点(用于旧版本)。

一个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

对于有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

当生成版本号时有文件未提交时,此处会出现脏标志。因为通常,当构建/打包应用程序时,每个代码修改都必须在存储库中。

我编写了一些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
}