修订号的Git等价物是多少?

Rad*_*dek 233 git version-control version-numbering revision-history

我们在工作中使用SVN,但对于我的个人项目,我决定使用Git.所以我昨天安装的Git,我不知道是什么版本号相当于在Git中.

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

max*_*max 174

使用现代Git(在我的情况下为1.8.3.4)并且不使用分支,您可以:

$ git rev-list --count HEAD
68
Run Code Online (Sandbox Code Playgroud)

  • 考虑使用`git rev-list --count --first-parent HEAD` (21认同)
  • 请记住,此解决方案将为不同的开发人员产生不同的结果.此外,从"计数"向后计算提交将为不同的开发人员提供不同的提交!这是因为Git的分布式特性,并且提交在同一块时间内发生在不同的存储库中,但可能不会计入`git rev-list --count HEAD`,具体取决于最后一次推送和拉取的时间. (9认同)
  • 鉴于此信息(数字68),有没有办法确定重新获取代码的修订?假设"版本68"已发布到测试环境,开发仍在继续,后来开发人员需要从源代码管理中重新获取"版本68".他将如何针对要克隆的特定版本?或者我错过了一些关于Git的东西,这使得这个不必要? (7认同)
  • @MarkHu,` - first-parent`有帮助.只要没有进行变基,并且总是使用相同的分支来进行发布(当然也计算这个版本号),我认为可以使用它.虽然,我仍然不确定它将始终唯一地标识发布来自的提交.这里有很多东西可能会出错...但是目前我无法想到一些肯定会破坏这一点的东西(鉴于我的上述"只要"陈述).另一个答案中提到的`git describe`方法是要走的路.如果您想要人类可读的内容,请创建标记. (4认同)
  • @Jason,大卫关于添加" - first-parent"的评论是否解决了你的问题?我讨厌避免一个看似最简单的解决方案,因为如果有一个同样简单的解决方法或方法使其更加健壮的罕见边缘情况. (2认同)
  • 很好的答案,但如何回去?假设我的项目版本为1.8.456.我怎样才能从456回来 - > 5ghj34ghj1234? (2认同)

mak*_*dad 142

好消息或坏消息,哈希是修订版号.当我从SVN切换到git时,我也遇到了麻烦.

您可以在git中使用"标记"将某个修订标记为特定版本的"发布",从而可以轻松引用该修订.看看这篇博文.

要理解的关键是git不能有修订号 - 考虑分散性.如果用户A和B都提交到他们的本地存储库,那么git如何合理地分配顺序修订版号?A在推/拉彼此的变化之前不知道B.

另一件需要注意的是针对bugfix分支的简化分支:

从版本开始:3.0.8.然后,在该版本之后,执行以下操作:

git branch bugfixes308
Run Code Online (Sandbox Code Playgroud)

这将为错误修正创建一个分支.结帐分支:

git checkout bugfixes308
Run Code Online (Sandbox Code Playgroud)

现在进行任何你想要的错误修改.

git commit -a
Run Code Online (Sandbox Code Playgroud)

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

git checkout master
Run Code Online (Sandbox Code Playgroud)

然后从另一个分支中提取这些更改:

git merge bugfixes308
Run Code Online (Sandbox Code Playgroud)

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

  • 我知道哈希是修订号,但我希望它不是:-)))非常好的解释和建议现在处理它. (11认同)
  • 此外,我发布此消息已经有一段时间了,但请记住,您也可以执行"git checkout -b new_branch_name"来执行"git branch foo"和"git checkout foo"作为一行. (4认同)
  • 别客气.当我第一次从SVN拿起它时,我对git非常沮丧,但现在我摇摆了另一种方式...... (3认同)
  • 在SVN中,在r42中已修复错误的事实并不能告诉您在实际使用分支后是否也在r43中也已修复了错误。 (3认同)

Gre*_*ill 100

git describe命令创建一个稍微更人性化的名称,引用特定的提交.例如,从文档中:

有了类似git.git当前树的东西,我得到:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721
Run Code Online (Sandbox Code Playgroud)

即我的"父"分支的当前头部基于v1.0.4,但由于它上面有一些提交,因此describe添加了额外提交的数量("14")和提交的缩写对象名称本身("2414721")在最后.

只要您使用合理命名的标签来标记特定版本,就可以认为这大致相当于SVN"版本号".

  • @sdaau:如果你在脚本或其他东西中使用它并希望`git describe`永不失败,请使用`git describe --always`选项. (14认同)
  • 我只想指出,如果你的`git`存储库已经有了标签,那么_only_就可以了.如果没有,你可能会得到[git describe失败的"致命:找不到名字,不能描述任何东西." - Stack Overflow](http://stackoverflow.com/questions/4916492/git-describe-fails-with-fatal-no-names-found-cannot-describe-anything); 这意味着你必须自己设置标签. (6认同)

Ode*_*Wat 66

其他海报是对的,没有"修订号".

我认为最好的方法是使用标签"发布"!

但我使用以下内容来伪造修订版号(仅供客户查看修订版和进度,因为他们希望从git获得与使用subversion时相同的增加修订版).

使用以下方法模拟显示​​"HEAD"的"当前版本":

git rev-list HEAD | wc -l

但如果客户告诉我"修订版"1302中有错误怎么办?

为此,我将以下内容添加到〜/ .gitconfig的[alias]部分:

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

git show-rev-number 1302然后使用将打印"修订版" 的哈希值 :)

不久前我做了一篇关于这种"技术" 的博客文章(德文版).

  • 我不得不使用`git rev-list --reverse HEAD | awk"{print NR}"| 尾巴-n 1` (3认同)

I G*_*ERS 25

Git没有与subversion相同的修订号概念.相反,使用提交创建的每个给定快照都由SHA1校验和标记.为什么?在分布式版本控制系统中运行revno有几个问题:

首先,由于开发根本不是线性的,所以数字的附加是一个难以解决的问题,以满足您作为程序员的需要.如果数字不符合您的预期,尝试通过添加数字来解决此问题可能很快就会出现问题.

其次,可以在不同的机器上生成修订号.这使得数字同步更加困难 - 特别是因为连接是单向的; 您可能甚至无法访问具有存储库的所有计算机.

第三,在git中,有点由现已解散的OpenCM系统开创,提交的标识(提交的内容)等同于其名称(SHA id).这个命名=身份概念非常强大.当您使用提交名称时,它还以不可伪造的方式标识提交.这反过来允许您使用该命令检查所有提交回到第一个初始提交git fsck.

现在,由于我们有一个DAG(有向无环图)的修订版,这些构成了当前的树,我们需要一些工具来解决你的问题:我们如何区分不同的版本.首先,如果给定的前缀1516bd表示唯一标识您的提交,则可以省略部分哈希.但这也是相当人为的.相反,诀窍是使用标签和/或分支.标记或分支类似于您附加到给定提交SHA1-id的"黄色标记".实质上,标签意味着不移动,而分支将在对其HEAD进行新提交时移动.有一些方法可以引用标记或分支周围的提交,请参阅git-rev-parse的手册页.

通常,如果您需要处理特定的代码片段,那么该片段正在进行更改,因此应该是具有说明主题名称的分支.创建大量的分支(每个程序员20-30个是闻所未闻的,其中有4-5个发布供其他人使用)是有效git的技巧.每一项工作都应该从它自己的分支开始,然后在测试时合并.未发表的分支可以完全重写,这部分破坏历史是git的力量.

当变化被主人接受时,它会冻结并变成考古学.此时,您可以对其进行标记,但更常见的是,通过sha1 sum在bug跟踪器或问题跟踪器中对特定提交进行引用.标签倾向于保留用于维护分支的版本颠簸和分支点(对于旧版本).


Seb*_*tte 17

如果你有兴趣,我设法从git的相关信息自动版本号在此格式下

<major>.<minor>.<patch>-b<build>
Run Code Online (Sandbox Code Playgroud)

其中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)
Run Code Online (Sandbox Code Playgroud)


siz*_*nax 9

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}
}
Run Code Online (Sandbox Code Playgroud)

输出类似的东西

$ git_rev
2:0f8e14e:20130220
Run Code Online (Sandbox Code Playgroud)

那是

commit_count:last_abbrev_commit:date_YYmmdd
Run Code Online (Sandbox Code Playgroud)


Ric*_*arn 8

提交SHA1哈希等同于Subversion修订号.

  • @Radek根据http://en.wikipedia.org/wiki/Collision_attack,有4个哈希字符,你有一个16位的Id,这意味着在一个拥有256(= 2 ^(16/2))提交的repo中两个提交有50%的可能性具有相同的四字符前缀(并且具有65536个提交,这是肯定的,因为那时4个字符ID的范围已经耗尽).当你添加一个char时,你有一个20位的Id,这意味着50%的阈值是1024次提交.但由于这是一个统计参数,没有什么能保证这种碰撞不会提前发生. (8认同)
  • 不幸的是,它与版本号具有完全不同的属性.它相当长,而且不会单调增加.猜猜这是分配的价格...... (7认同)
  • @Radek:他们不能保证独一无二(尽管如果你发现碰撞,你可以赢得少量名人). (5认同)
  • 由于散列基于内容,因此两个提交是否具有相同的散列前缀仍然是一个概率,而不是确定性.在65536提交它很可能两个将具有相同的四字符前缀,但它仍然不确定.顺便说一下,完整哈希还没有碰撞,但是git正在研究它:) http://stackoverflow.com/questions/3475648/sha1-collision-demo-example#comment6046971_3476791 (2认同)

小智 6

这是我在基于其他解决方案的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
Run Code Online (Sandbox Code Playgroud)

  • 看来使用git-describe避免错误的最安全方法是使用git describe --always --dirty --long --tags`,这种方法在我能想到的所有情况下都有效。 (3认同)

Cor*_*Xii 5

每个提交都有一个唯一的哈希值。除此之外,git 中没有修订号。如果你想要更多的用户友好性,你必须自己标记提交。


Jim*_*ton 5

使用git hash作为内部版本号的问题在于它不会单调增加。OSGi建议使用时间戳作为内部版本号。看起来可以使用分支的提交次数来代替Subversion或perforce更改次数。


小智 5

我编写了一些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
}
Run Code Online (Sandbox Code Playgroud)